Passed
Push — master ( 655c1d...ec995b )
by Dmitry
36s
created

Process::getMemoryUsage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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