Test Failed
Push — master ( 817d84...d52e3d )
by Raffael
05:44
created

Elasticsearch   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 172
Duplicated Lines 13.37 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 2
dl 23
loc 172
ccs 0
cts 96
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 8 8 1
B __invoke() 0 45 6
A setOptions() 15 15 3
A getOperands() 0 6 1
A getOptions() 0 7 1
A index() 0 30 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon\App\Elasticsearch\Console;
13
14
use Balloon\App\Elasticsearch\Job;
15
use Balloon\Filesystem;
16
use Balloon\Server;
17
use GetOpt\GetOpt;
18
use InvalidArgumentException;
19
use MongoDB\Driver\Exception\ServerException;
20
use Psr\Log\LoggerInterface;
21
use TaskScheduler\Scheduler;
22
23
class Elasticsearch
24
{
25
    /**
26
     * Logger.
27
     *
28
     * @var LoggerInterface
29
     */
30
    protected $logger;
31
32
    /**
33
     * Getopt.
34
     *
35
     * @var GetOpt
36
     */
37
    protected $getopt;
38
39
    /**
40
     * Scheduler.
41
     *
42
     * @var Scheduler
43
     */
44
    protected $scheduler;
45
46
    /**
47
     * Filesystem.
48
     *
49
     * @var Filesystem
50
     */
51
    protected $fs;
52
53
    /**
54
     * Bulk.
55
     *
56
     * @var int
57
     */
58
    protected $bulk = 200;
59
60
    /**
61
     * Constructor.
62
     */
63 View Code Duplication
    public function __construct(GetOpt $getopt, Server $server, Scheduler $scheduler, LoggerInterface $logger, array $config = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
    {
65
        $this->logger = $logger;
66
        $this->getopt = $getopt;
67
        $this->fs = $server->getFilesystem();
68
        $this->scheduler = $scheduler;
69
        $this->setOptions($config);
70
    }
71
72
    /**
73
     * Reindex elasticsearch.
74
     */
75
    public function __invoke(): bool
76
    {
77
        if (!in_array('reindex', $this->getopt->getOperands())) {
78
            echo $this->getopt->getHelpText();
79
80
            return false;
81
        }
82
83
        $total = $this->fs->countNodes();
84
        $stack = [];
0 ignored issues
show
Unused Code introduced by
$stack is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
85
        $done = 0;
0 ignored issues
show
Unused Code introduced by
$done is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
86
        $result = false;
87
        $skip = $this->getopt->getOption('skip') | 0;
88
        $this->bulk = $this->getopt->getOption('bulk') ? (int) $this->getopt->getOption('bulk') : $this->bulk;
89
        $total -= $skip;
90
91
        if ($total < 0) {
92
            $total = 0;
93
        }
94
95
        $this->logger->info('reindex elasticsearch, nodes left: {total}/{total}', [
96
            'category' => get_class($this),
97
            'total' => $total,
98
        ]);
99
100
        $stack = [];
0 ignored issues
show
Unused Code introduced by
$stack is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
101
        $done = 0;
0 ignored issues
show
Unused Code introduced by
$done is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
102
103
        while ($result === false) {
104
            try {
105
                $this->index($total, $skip);
106
                $result = true;
107
            } catch (ServerException $e) {
0 ignored issues
show
Bug introduced by
The class MongoDB\Driver\Exception\ServerException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
108
                $skip -= $this->bulk;
109
110
                $this->logger->error('cursor timeout captchered, restart from {skip}', [
111
                    'category' => get_class($this),
112
                    'exception' => $e,
113
                    'skip' => $skip,
114
                ]);
115
            }
116
        }
117
118
        return true;
119
    }
120
121
    /**
122
     * Set options.
123
     */
124 View Code Duplication
    public function setOptions(array $config = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
125
    {
126
        foreach ($config as $key => $value) {
127
            switch ($key) {
128
                case 'bulk':
129
                    $this->{$key} = (int) $value;
130
131
                break;
132
                default:
133
                    throw new InvalidArgumentException('invalid option '.$key.' given');
134
            }
135
        }
136
137
        return $this;
138
    }
139
140
    /**
141
     * Get operands.
142
     */
143
    public static function getOperands(): array
144
    {
145
        return [
146
            \GetOpt\Operand::create('reindex')->setDescription('Reindex entire elasticsearch indices, note this may take a while according to your number of nodes)'),
147
        ];
148
    }
149
150
    /**
151
     * Get options.
152
     */
153
    public static function getOptions(): array
154
    {
155
        return [
156
            \GetOpt\Option::create('b', 'bulk', \GetOpt\GetOpt::REQUIRED_ARGUMENT)->setDescription('Specify the bulk size [Default: 200]'),
157
            \GetOpt\Option::create('s', 'skip', \GetOpt\GetOpt::REQUIRED_ARGUMENT)->setDescription('Instead start from node 0, you may skip nodes by specifing a different start index'),
158
        ];
159
    }
160
161
    /**
162
     * Index.
163
     */
164
    protected function index(int $total = 0, int &$done = 0): bool
165
    {
166
        $stack = [];
167
168
        foreach ($this->fs->findNodesByFilter([], $done) as $node) {
169
            $stack[] = $this->scheduler->addJob(Job::class, [
170
                'id' => $node->getId(),
171
                'action' => Job::ACTION_CREATE,
172
            ]);
173
174
            if (count($stack) >= $this->bulk) {
175
                $this->logger->info('waiting for ['.$this->bulk.'] jobs to be finished', [
176
                    'category' => get_class($this),
177
                ]);
178
179
                $done += $this->bulk;
180
                $this->logger->info('reindex elasticsearch {percent}, nodes left: {done}/{total}', [
181
                    'category' => get_class($this),
182
                    'percent' => round($done / $total * 100, 1).'%',
183
                    'total' => $total,
184
                    'done' => $done,
185
                ]);
186
187
                $this->scheduler->waitFor($stack);
188
                $stack = [];
189
            }
190
        }
191
192
        return true;
193
    }
194
}
195