Passed
Push — renovate/php-8.x ( bfb893...222c0a )
by
unknown
02:20
created

TopLikeCommand::execute()   B

Complexity

Conditions 6
Paths 1

Size

Total Lines 76
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 6
eloc 51
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 76
rs 8.4468

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 PhpProfiler\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 PhpProfiler\Inspector\Daemon\Dispatcher\DispatchTable;
19
use PhpProfiler\Inspector\Daemon\Dispatcher\WorkerPool;
20
use PhpProfiler\Inspector\Daemon\Reader\Context\PhpReaderContextCreator;
21
use PhpProfiler\Inspector\Daemon\Reader\Protocol\Message\TraceMessage;
22
use PhpProfiler\Inspector\Daemon\Searcher\Context\PhpSearcherContextCreator;
23
use PhpProfiler\Inspector\Output\TopLike\TopLikeFormatter;
24
use PhpProfiler\Inspector\Output\TopLike\TopLikeFormatterFactory;
25
use PhpProfiler\Inspector\Settings\DaemonSettings\DaemonSettingsFromConsoleInput;
26
use PhpProfiler\Inspector\Settings\GetTraceSettings\GetTraceSettingsFromConsoleInput;
27
use PhpProfiler\Inspector\Settings\TargetPhpSettings\TargetPhpSettingsFromConsoleInput;
28
use PhpProfiler\Inspector\Settings\TraceLoopSettings\TraceLoopSettingsFromConsoleInput;
29
use PhpProfiler\Lib\Console\EchoBackCanceller;
30
use PhpProfiler\Lib\Log\Log;
31
use PhpProfiler\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($searcher_context->sendTargetRegex($daemon_settings->target_regex));
79
80
        $worker_pool = WorkerPool::create(
81
            $this->php_reader_context_creator,
82
            $daemon_settings->threads,
83
            $target_php_settings,
84
            $loop_settings,
85
            $get_trace_settings
86
        );
87
88
        $dispatch_table = new DispatchTable(
89
            $worker_pool,
90
        );
91
92
        $_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...
93
94
        Loop::onReadable(
95
            STDIN,
96
            /** @param resource $stream */
97
            function (string $watcher_id, $stream) {
98
                $key = fread($stream, 1);
99
                if ($key === 'q') {
100
                    Loop::cancel($watcher_id);
101
                    Loop::stop();
102
                }
103
            }
104
        );
105
        Loop::run(function () use ($dispatch_table, $searcher_context, $worker_pool, $formatter) {
106
            $promises = [];
107
            $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

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