DaemonCommand::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 8
dl 0
loc 11
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * This file is part of the sj-i/php-profiler 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\Reader\Protocol\Message\TraceMessage;
20
use PhpProfiler\Inspector\Daemon\Dispatcher\WorkerPool;
21
use PhpProfiler\Inspector\Daemon\Reader\Context\PhpReaderContextCreator;
22
use PhpProfiler\Inspector\Daemon\Searcher\Context\PhpSearcherContextCreator;
23
use PhpProfiler\Inspector\Output\TraceFormatter\CallTraceFormatter;
24
use PhpProfiler\Inspector\Output\TraceFormatter\Templated\TemplatedTraceFormatterFactory;
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\TemplatedTraceFormatterSettings\TemplateSettingsFromConsoleInput;
29
use PhpProfiler\Inspector\Settings\TraceLoopSettings\TraceLoopSettingsFromConsoleInput;
30
use PhpProfiler\Lib\Console\EchoBackCanceller;
31
use PhpProfiler\Lib\Log\Log;
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
use function fread;
38
39
use const STDIN;
40
41
final class DaemonCommand extends Command
42
{
43
    public function __construct(
44
        private PhpSearcherContextCreator $php_searcher_context_creator,
45
        private PhpReaderContextCreator $php_reader_context_creator,
46
        private DaemonSettingsFromConsoleInput $daemon_settings_from_console_input,
47
        private GetTraceSettingsFromConsoleInput $get_trace_settings_from_console_input,
48
        private TargetPhpSettingsFromConsoleInput $target_php_settings_from_console_input,
49
        private TraceLoopSettingsFromConsoleInput $trace_loop_settings_from_console_input,
50
        private TemplateSettingsFromConsoleInput $template_settings_from_console_input,
51
        private TemplatedTraceFormatterFactory $templated_trace_formatter_factory,
52
    ) {
53
        parent::__construct();
54
    }
55
56
    public function configure(): void
57
    {
58
        $this->setName('inspector:daemon')
59
            ->setDescription('concurrently get call traces from processes whose command-lines match a given regex')
60
        ;
61
        $this->daemon_settings_from_console_input->setOptions($this);
62
        $this->get_trace_settings_from_console_input->setOptions($this);
63
        $this->trace_loop_settings_from_console_input->setOptions($this);
64
        $this->target_php_settings_from_console_input->setOptions($this);
65
        $this->template_settings_from_console_input->setOptions($this);
66
    }
67
68
    public function execute(InputInterface $input, OutputInterface $output): int
69
    {
70
        $get_trace_settings = $this->get_trace_settings_from_console_input->createSettings($input);
71
        $daemon_settings = $this->daemon_settings_from_console_input->createSettings($input);
72
        $target_php_settings = $this->target_php_settings_from_console_input->createSettings($input);
73
        $loop_settings = $this->trace_loop_settings_from_console_input->createSettings($input);
74
        $template_settings = $this->template_settings_from_console_input->createSettings($input);
75
        $formatter = $this->templated_trace_formatter_factory->createFromSettings($template_settings);
76
77
        $searcher_context = $this->php_searcher_context_creator->create();
78
        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

78
        /** @scrutinizer ignore-call */ 
79
        Promise\wait($searcher_context->start());
Loading history...
79
        Promise\wait($searcher_context->sendTargetRegex($daemon_settings->target_regex));
80
81
        $worker_pool = WorkerPool::create(
82
            $this->php_reader_context_creator,
83
            $daemon_settings->threads,
84
            $target_php_settings,
85
            $loop_settings,
86
            $get_trace_settings
87
        );
88
89
        $dispatch_table = new DispatchTable(
90
            $worker_pool,
91
        );
92
93
        $_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...
94
95
        Loop::onReadable(
96
            STDIN,
97
            /** @param resource $stream */
98
            function (string $watcher_id, $stream) {
99
                $key = fread($stream, 1);
100
                if ($key === 'q') {
101
                    Loop::cancel($watcher_id);
102
                    Loop::stop();
103
                }
104
            }
105
        );
106
        Loop::run(function () use ($dispatch_table, $searcher_context, $worker_pool, $output, $formatter) {
107
            $promises = [];
108
            $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

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