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

DaemonCommand::execute()   B

Complexity

Conditions 6
Paths 1

Size

Total Lines 77
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 51
nc 1
nop 2
dl 0
loc 77
rs 8.4468
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 reliforp/reli-prof 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\Reader\Protocol\Message\TraceMessage;
20
use Reli\Inspector\Daemon\Dispatcher\WorkerPool;
21
use Reli\Inspector\Daemon\Reader\Context\PhpReaderContextCreator;
22
use Reli\Inspector\Daemon\Searcher\Context\PhpSearcherContextCreator;
23
use Reli\Inspector\Output\TraceOutput\TraceOutputFactory;
24
use Reli\Inspector\Settings\DaemonSettings\DaemonSettingsFromConsoleInput;
25
use Reli\Inspector\Settings\GetTraceSettings\GetTraceSettingsFromConsoleInput;
26
use Reli\Inspector\Settings\OutputSettings\OutputSettingsFromConsoleInput;
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 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...
32
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...
33
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...
34
35
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...
36
use function fread;
37
38
use const STDIN;
39
40
final class DaemonCommand extends Command
41
{
42
    public function __construct(
43
        private PhpSearcherContextCreator $php_searcher_context_creator,
44
        private PhpReaderContextCreator $php_reader_context_creator,
45
        private DaemonSettingsFromConsoleInput $daemon_settings_from_console_input,
46
        private GetTraceSettingsFromConsoleInput $get_trace_settings_from_console_input,
47
        private TargetPhpSettingsFromConsoleInput $target_php_settings_from_console_input,
48
        private TraceLoopSettingsFromConsoleInput $trace_loop_settings_from_console_input,
49
        private OutputSettingsFromConsoleInput $output_settings_from_console_input,
50
        private TraceOutputFactory $trace_output_factory,
51
    ) {
52
        parent::__construct();
53
    }
54
55
    public function configure(): void
56
    {
57
        $this->setName('inspector:daemon')
58
            ->setDescription('concurrently get call traces from processes whose command-lines match a given regex')
59
        ;
60
        $this->daemon_settings_from_console_input->setOptions($this);
61
        $this->get_trace_settings_from_console_input->setOptions($this);
62
        $this->trace_loop_settings_from_console_input->setOptions($this);
63
        $this->target_php_settings_from_console_input->setOptions($this);
64
        $this->output_settings_from_console_input->setOptions($this);
65
    }
66
67
    public function execute(InputInterface $input, OutputInterface $output): int
68
    {
69
        $get_trace_settings = $this->get_trace_settings_from_console_input->createSettings($input);
70
        $daemon_settings = $this->daemon_settings_from_console_input->createSettings($input);
71
        $target_php_settings = $this->target_php_settings_from_console_input->createSettings($input);
72
        $loop_settings = $this->trace_loop_settings_from_console_input->createSettings($input);
73
        $trace_output = $this->trace_output_factory->fromSettingsAndConsoleOutput(
74
            $output,
75
            $this->output_settings_from_console_input->createSettings($input),
76
        );
77
78
        $searcher_context = $this->php_searcher_context_creator->create();
79
        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

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

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