Passed
Push — master ( 745402...3d5cea )
by Marcel
43s
created

ConcurrentServer::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 9
ccs 4
cts 5
cp 0.8
crap 2.032
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace UMA\JsonRpc;
6
7
use Psr\Container\ContainerInterface;
8
use UMA\JsonRpc\Internal\Input;
9
10
/**
11
 * Experimental concurrent Server. Needs the pcntl extension,
12
 * therefore it can only work in the CLI SAPI.
13
 *
14
 * /!\ Probably NOT fit for production usage.
15
 */
16
class ConcurrentServer extends Server
17
{
18 16
    public function __construct(ContainerInterface $container, int $batchLimit = null)
19
    {
20 16
        if (!\extension_loaded('pcntl')) {
21
            throw new \RuntimeException('ConcurrentServer relies on the pcntl extension');
22
        }
23
24 16
        \pcntl_async_signals(true);
25
26 16
        parent::__construct($container, $batchLimit);
27 16
    }
28
29 6
    protected function batch(Input $input): ?string
30
    {
31 6
        \assert($input->isArray());
32
33 6
        if ($this->tooManyBatchRequests($input)) {
34 1
            return self::end(Error::tooManyBatchRequests($this->batchLimit));
35
        }
36
37 5
        $children = [];
38 5
        $responses = [];
39 5
        foreach ($input->data() as $request) {
40 5
            $pair = \stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
41
42 5
            $pid = \pcntl_fork();
43
44 5
            if (0 === $pid) {
45
                \fclose($pair[0]);
46
47
                \fwrite($pair[1], $this->single(Input::fromSafeData($request)) . "\n");
48
49
                \fclose($pair[1]);
50
51
                exit(0);
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
52
            }
53
54 5
            \fclose($pair[1]);
55
56 5
            $children[$pid] = $pair[0];
57
        }
58
59 5
        foreach ($children as $pid => $socket) {
60 5
            \pcntl_waitpid($pid, $status);
61
62 5
            if ('' !== $response = \trim(\fgets($socket))) {
63 4
                $responses[] = $response;
64
            }
65
66 5
            \fclose($socket);
67
        }
68
69 5
        return empty($responses) ?
70 5
            null : \sprintf('[%s]', \implode(',', $responses));
71
    }
72
}
73