Process::setAllowedFork()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace SymfonyBundles\Fork;
4
5
class Process implements ProcessInterface
6
{
7
    /**
8
     * @var bool
9
     */
10
    protected $allowedFork;
11
12
    /**
13
     * @var int
14
     */
15
    protected $processesCount;
16
17
    /**
18
     * Constructor.
19
     */
20 9
    public function __construct()
21
    {
22 9
        $this->setAllowedFork(function_exists('pcntl_fork'));
23 9
    }
24
25
    /**
26
     * {@inheritdoc}
27
     */
28 9
    public function setAllowedFork(bool $allowedFork): void
29
    {
30 9
        $this->allowedFork = $allowedFork;
31 9
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36 3
    public function create(\Closure $closure): ProcessInterface
37
    {
38 3
        for ($i = 0; $i < $this->processesCount; ++$i) {
39 3
            if ($this->fork()) {
40 2
                $closure();
41
42 2
                $this->terminate();
43
            }
44
        }
45
46 3
        return $this;
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52 1
    public function wait(): ProcessInterface
53
    {
54 1
        if ($this->allowedFork) {
55 1
            pcntl_wait($status);
56
        }
57
58 1
        return $this;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 2
    public function getPid(): int
65
    {
66 2
        return getmypid();
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     *
72
     * @codeCoverageIgnore
73
     */
74
    public function isAlive(int $pid): bool
75
    {
76
        if (0 === strncasecmp(PHP_OS, 'win', 3)) {
77
            exec(sprintf('TASKLIST /FO LIST /FI "PID eq %d"', $pid), $info);
78
79
            return count($info) > 1;
80
        }
81
82
        return posix_kill($pid, 0);
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 1
    public function getMemoryUsage(): float
89
    {
90 1
        return round(memory_get_usage(true) / 1024 / 1024, 2);
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 5
    public function setCountOfChildProcesses(int $processesCount): ProcessInterface
97
    {
98 5
        if ($processesCount < 1) {
99 2
            $processesCount = $this->getOptimalNumberOfChildProcesses();
100
        }
101
102 5
        if ($processesCount > static::MAX_PROCESSES_QUANTITY) {
103 1
            $processesCount = static::MAX_PROCESSES_QUANTITY;
104
        }
105
106 5
        if ($this->allowedFork) {
107 4
            $this->processesCount = $processesCount;
108
        } else {
109 1
            $this->processesCount = 1;
110
        }
111
112 5
        return $this;
113
    }
114
115
    /**
116
     * @return bool Returns TRUE if this is a child process, else - FALSE
117
     */
118 2
    protected function fork(): bool
119
    {
120 2
        if ($this->allowedFork) {
121 1
            return 0 === pcntl_fork();
122
        }
123
124 1
        return true;
125
    }
126
127
    /**
128
     * @codeCoverageIgnore
129
     *
130
     * @return bool
131
     */
132
    protected function terminate(): bool
133
    {
134
        if ($this->allowedFork) {
135
            return posix_kill(getmypid(), SIGKILL);
136
        }
137
138
        return true;
139
    }
140
141
    /**
142
     * Returns the optimal number of child processes.
143
     *
144
     * @return int
145
     */
146 2
    protected function getOptimalNumberOfChildProcesses(): int
147
    {
148 2
        $coreNumber = 1;
149
        $detectCommand = [
150 2
            'linux' => 'cat /proc/cpuinfo | grep processor | wc -l',
151
        ];
152
153 2
        $os = strtolower(trim(PHP_OS));
154
155 2
        if (isset($detectCommand[$os])) {
156 2
            $coreNumber = intval($this->execute($detectCommand[$os]));
157
        }
158
159 2
        return $coreNumber;
160
    }
161
162
    /**
163
     * @param string $command
164
     *
165
     * @return string
166
     */
167 2
    protected function execute(string $command): string
168
    {
169 2
        return trim(shell_exec($command));
170
    }
171
}
172