Passed
Push — 0.6.x ( 9a1948...a98caa )
by Shinji
03:23 queued 01:32
created

TopLikeCommand::execute()   B

Complexity

Conditions 6
Paths 1

Size

Total Lines 80
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 53
nc 1
nop 2
dl 0
loc 80
rs 8.4032
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file is part of the sj-i/ package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Reli\Command\Inspector;
15
16
use Amp\Loop;
0 ignored issues
show
Bug introduced by
The type Amp\Loop was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Amp\Promise;
0 ignored issues
show
Bug introduced by
The type Amp\Promise was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Reli\Inspector\Daemon\Dispatcher\DispatchTable;
19
use Reli\Inspector\Daemon\Dispatcher\WorkerPool;
20
use Reli\Inspector\Daemon\Reader\Context\PhpReaderContextCreator;
21
use Reli\Inspector\Daemon\Reader\Protocol\Message\TraceMessage;
22
use Reli\Inspector\Daemon\Searcher\Context\PhpSearcherContextCreator;
23
use Reli\Inspector\Output\TopLike\TopLikeFormatter;
24
use Reli\Inspector\Output\TopLike\TopLikeFormatterFactory;
25
use Reli\Inspector\Settings\DaemonSettings\DaemonSettingsFromConsoleInput;
26
use Reli\Inspector\Settings\GetTraceSettings\GetTraceSettingsFromConsoleInput;
27
use Reli\Inspector\Settings\TargetPhpSettings\TargetPhpSettingsFromConsoleInput;
28
use Reli\Inspector\Settings\TraceLoopSettings\TraceLoopSettingsFromConsoleInput;
29
use Reli\Lib\Console\EchoBackCanceller;
30
use Reli\Lib\Log\Log;
31
use Reli\Lib\PhpProcessReader\CallTrace;
32
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
33
use Symfony\Component\Console\Input\InputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
use Symfony\Component\Console\Output\OutputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Output\OutputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
36
use function Amp\call;
0 ignored issues
show
introduced by
The function Amp\call was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
37
38
final class TopLikeCommand extends Command
39
{
40
    public function __construct(
41
        private PhpSearcherContextCreator $php_searcher_context_creator,
42
        private PhpReaderContextCreator $php_reader_context_creator,
43
        private DaemonSettingsFromConsoleInput $daemon_settings_from_console_input,
44
        private GetTraceSettingsFromConsoleInput $get_trace_settings_from_console_input,
45
        private TargetPhpSettingsFromConsoleInput $target_php_settings_from_console_input,
46
        private TraceLoopSettingsFromConsoleInput $trace_loop_settings_from_console_input,
47
        private TopLikeFormatterFactory $formatter_factory,
48
    ) {
49
        parent::__construct();
50
    }
51
52
    public function configure(): void
53
    {
54
        $this->setName('inspector:top')
55
            ->setDescription(
56
                'show an aggregated view of traces in real time in a form similar to the UNIX top command.'
57
            )
58
        ;
59
        $this->daemon_settings_from_console_input->setOptions($this);
60
        $this->get_trace_settings_from_console_input->setOptions($this);
61
        $this->trace_loop_settings_from_console_input->setOptions($this);
62
        $this->target_php_settings_from_console_input->setOptions($this);
63
    }
64
65
    public function execute(InputInterface $input, OutputInterface $output): int
66
    {
67
        $get_trace_settings = $this->get_trace_settings_from_console_input->createSettings($input);
68
        $daemon_settings = $this->daemon_settings_from_console_input->createSettings($input);
69
        $target_php_settings = $this->target_php_settings_from_console_input->createSettings($input);
70
        $loop_settings = $this->trace_loop_settings_from_console_input->createSettings($input);
71
        $formatter = $this->formatter_factory->create(
72
            $daemon_settings->target_regex,
73
            $output
74
        );
75
76
        $searcher_context = $this->php_searcher_context_creator->create();
77
        Promise\wait($searcher_context->start());
0 ignored issues
show
Bug introduced by
The function wait was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
        /** @scrutinizer ignore-call */ 
78
        Promise\wait($searcher_context->start());
Loading history...
78
        Promise\wait(
79
            $searcher_context->sendTarget(
80
                $daemon_settings->target_regex,
81
                $target_php_settings,
82
            )
83
        );
84
85
        $worker_pool = WorkerPool::create(
86
            $this->php_reader_context_creator,
87
            $daemon_settings->threads,
88
            $loop_settings,
89
            $get_trace_settings
90
        );
91
92
        $dispatch_table = new DispatchTable(
93
            $worker_pool,
94
        );
95
96
        $_echo_back_canceler = new EchoBackCanceller();
0 ignored issues
show
Unused Code introduced by
The assignment to $_echo_back_canceler is dead and can be removed.
Loading history...
97
98
        Loop::onReadable(
99
            STDIN,
100
            /** @param resource $stream */
101
            function (string $watcher_id, $stream) {
102
                $key = fread($stream, 1);
103
                if ($key === 'q') {
104
                    Loop::cancel($watcher_id);
105
                    Loop::stop();
106
                }
107
            }
108
        );
109
        Loop::run(function () use ($dispatch_table, $searcher_context, $worker_pool, $formatter) {
110
            $promises = [];
111
            $promises[] = call(function () use ($searcher_context, $dispatch_table) {
0 ignored issues
show
Bug introduced by
The function call was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
            $promises[] = /** @scrutinizer ignore-call */ call(function () use ($searcher_context, $dispatch_table) {
Loading history...
112
                while (1) {
113
                    Log::debug('receiving pid List');
114
                    $update_target_message = yield $searcher_context->receivePidList();
115
                    Log::debug('update targets', [
116
                        'update' => $update_target_message->target_process_list->getArray(),
117
                        'current' => $dispatch_table->worker_pool->debugDump(),
118
                    ]);
119
                    $dispatch_table->updateTargets($update_target_message->target_process_list);
120
                    Log::debug('target updated', [$dispatch_table->worker_pool->debugDump()]);
121
                }
122
            });
123
            foreach ($worker_pool->getWorkers() as $reader) {
124
                $promises[] = call(
125
                    function () use ($reader, $dispatch_table, $formatter) {
126
                        while (1) {
127
                            $result = yield $reader->receiveTraceOrDetachWorker();
128
                            if ($result instanceof TraceMessage) {
129
                                $this->outputTrace($formatter, $result);
130
                            } else {
131
                                Log::debug('releaseOne', [$result]);
132
                                $dispatch_table->releaseOne($result->pid);
133
                                $this->outputTrace($formatter, new TraceMessage(
134
                                    new CallTrace()
135
                                ));
136
                            }
137
                        }
138
                    }
139
                );
140
            }
141
            yield $promises;
142
        });
143
144
        return 0;
145
    }
146
147
    private function outputTrace(
148
        TopLikeFormatter $formatter,
149
        TraceMessage $message
150
    ): void {
151
        $formatter->format($message->trace);
152
    }
153
}
154