Passed
Push — master ( 746356...c5b336 )
by Dmitry
38s
created

Process::setAllowedFork()   A

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
        return posix_kill($pid, 0);
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 1
    public function getMemoryUsage(): float
83
    {
84 1
        return round(memory_get_usage(true) / 1024 / 1024, 2);
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 5
    public function setCountOfChildProcesses(int $processesCount): ProcessInterface
91
    {
92 5
        if ($processesCount < 1) {
93 2
            $processesCount = $this->getOptimalNumberOfChildProcesses();
94
        }
95
96 5
        if ($processesCount > static::MAX_PROCESSES_QUANTITY) {
97 1
            $processesCount = static::MAX_PROCESSES_QUANTITY;
98
        }
99
100 5
        if ($this->allowedFork) {
101 4
            $this->processesCount = $processesCount;
102
        } else {
103 1
            $this->processesCount = 1;
104
        }
105
106 5
        return $this;
107
    }
108
109
    /**
110
     * @return bool Returns TRUE if this is a child process, else - FALSE
111
     */
112 2
    protected function fork(): bool
113
    {
114 2
        if ($this->allowedFork) {
115 1
            return 0 === pcntl_fork();
116
        }
117
118 1
        return true;
119
    }
120
121
    /**
122
     * @codeCoverageIgnore
123
     *
124
     * @return bool
125
     */
126
    protected function terminate(): bool
127
    {
128
        if ($this->allowedFork) {
129
            return posix_kill(getmypid(), SIGKILL);
130
        }
131
132
        return true;
133
    }
134
135
    /**
136
     * Returns the optimal number of child processes.
137
     *
138
     * @return int
139
     */
140 2
    protected function getOptimalNumberOfChildProcesses(): int
141
    {
142 2
        $coreNumber = 1;
143
        $detectCommand = [
144 2
            'linux' => 'cat /proc/cpuinfo | grep processor | wc -l',
145
        ];
146
147 2
        $os = strtolower(trim(PHP_OS));
148
149 2
        if (isset($detectCommand[$os])) {
150 2
            $coreNumber = intval($this->execute($detectCommand[$os]));
151
        }
152
153 2
        return $coreNumber;
154
    }
155
156
    /**
157
     * @param string $command
158
     *
159
     * @return string
160
     */
161 2
    protected function execute(string $command): string
162
    {
163 2
        return trim(shell_exec($command));
164
    }
165
}
166