Passed
Push — 0.4 ( 487c21 )
by jean
05:10
created

LaunchIsolateProcessStep::execute()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
nc 16
nop 1
dl 0
loc 44
ccs 29
cts 29
cp 1
crap 5
rs 8.9048
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Darkilliant\ProcessBundle\Step;
6
7
use Darkilliant\ProcessBundle\State\ProcessState;
8
use Symfony\Component\Console\ConsoleEvents;
9
use Symfony\Component\Console\Event\ConsoleEvent;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
12
use Symfony\Component\OptionsResolver\OptionsResolver;
13
use Symfony\Component\Process\PhpExecutableFinder;
14
use Symfony\Component\Process\Process;
15
use Symfony\Component\Process\ProcessBuilder;
16
17
class LaunchIsolateProcessStep extends AbstractConfigurableStep implements EventSubscriberInterface
18
{
19
    private $processCollection = [];
20
    private $verbosity;
21
    private $environment;
22
23 8
    public function __construct($environment)
24
    {
25 8
        $this->environment = $environment;
26 8
    }
27
28
    /**
29
     * @codeCoverageIgnore
30
     */
31
    public static function getSubscribedEvents()
32
    {
33
        return [
34
            ConsoleEvents::COMMAND => ['onCommand', 255],
35
        ];
36
    }
37
38 6
    public function onCommand(ConsoleEvent $event)
39
    {
40 6
        $this->verbosity = $event->getOutput()->getVerbosity();
41 6
    }
42
43 1
    public function configureOptionResolver(OptionsResolver $resolver): OptionsResolver
44
    {
45 1
        $resolver->setRequired(['process_name', 'max_concurency', 'context', 'data', 'timeout', 'bin_console_path']);
46 1
        $resolver->setDefault('context', []);
47 1
        $resolver->setDefault('data', []);
48 1
        $resolver->setDefault('max_concurency', 1);
49 1
        $resolver->setDefault('timeout', 60 * 20);
50
51 1
        return parent::configureOptionResolver($resolver);
52
    }
53
54 7
    public function execute(ProcessState $state)
55
    {
56 7
        $processName = $state->getOptions()['process_name'];
57 7
        $maxConcurency = $state->getOptions()['max_concurency'];
58 7
        $context = $state->getOptions()['context'];
59 7
        $data = $state->getOptions()['data'];
60
61 7
        $processBuilder = $this->getProcessBuilder();
62 7
        $phpFinder = $this->getPhpExecutableFinder();
63
64
        $arguments = [
65 7
            $phpFinder->find(),
66 7
            $state->getOptions()['bin_console_path'],
67 7
            'process:run',
68 7
            '--env=prod',
69 7
            '--input-from-stdin',
70 7
            '--force-color',
71
        ];
72
73 7
        $verbosityParameter = $this->getVerbosityParameter();
74 7
        if ($verbosityParameter) {
75 5
            $arguments[] = $verbosityParameter;
76
        }
77
78 7
        foreach ($context as $key => $value) {
79 7
            $arguments[] = sprintf('--context %s=%s', $key, $value);
80
        }
81
82 7
        if ($state->isDryRun()) {
83 1
            $arguments[] = '--dry-run';
84
        }
85
86 7
        $arguments[] = '--';
87 7
        $arguments[] = $processName;
88 7
        $processBuilder->setArguments($arguments);
89
90 7
        $processBuilder->setInput(json_encode($data));
91 7
        $processBuilder->setTimeout($state->getOptions()['timeout']);
92 7
        $process = $processBuilder->getProcess();
93
94 7
        $this->processCollection[] = $process;
95
96 7
        if (count($this->processCollection) >= $maxConcurency) {
97 7
            $this->wait();
98
        }
99 7
    }
100
101 7
    public function finalize(ProcessState $state)
102
    {
103 7
        $this->wait();
104 7
    }
105
106
    /**
107
     * @codeCoverageIgnore
108
     */
109
    protected function getProcessBuilder(): ProcessBuilder
110
    {
111
        return new ProcessBuilder();
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Process\ProcessBuilder has been deprecated: since version 3.4, to be removed in 4.0. Use the Process class instead. ( Ignorable by Annotation )

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

111
        return /** @scrutinizer ignore-deprecated */ new ProcessBuilder();
Loading history...
112
    }
113
114
    /**
115
     * @codeCoverageIgnore
116
     */
117
    protected function getPhpExecutableFinder(): PhpExecutableFinder
118
    {
119
        return new PhpExecutableFinder();
120
    }
121
122 7
    protected function getVerbosityParameter()
123
    {
124 7
        if (!$this->verbosity) {
125 1
            return '-vv';
126
        }
127 6
        switch ($this->verbosity) {
128 6
            case OutputInterface::VERBOSITY_QUIET:
129 1
                return '-q';
130 5
            case OutputInterface::VERBOSITY_VERBOSE:
131 1
                return '-v';
132 4
            case OutputInterface::VERBOSITY_VERY_VERBOSE:
133 1
                return '-vv';
134 3
            case OutputInterface::VERBOSITY_DEBUG:
135 1
                return '-vvv';
136
        }
137
138 2
        return null;
139
    }
140
141 7
    private function wait()
142
    {
143 7
        while (count($this->processCollection) > 0) {
144 7
            foreach ($this->processCollection as $i => $process) {
145 7
                if (!$process->isStarted()) {
146 7
                    echo "Process starts\n";
147
148 7
                    $process->start();
149
150 7
                    continue;
151
                }
152
153 7
                echo $process->getIncrementalOutput();
154 7
                echo $process->getIncrementalErrorOutput();
155
156 7
                if (!$process->isRunning()) {
157 7
                    echo "Process stopped\n";
158
159 7
                    unset($this->processCollection[$i]);
160
                }
161
            }
162
163 7
            sleep(1);
164
        }
165 7
        $this->processCollection = [];
166 7
    }
167
}
168