Completed
Pull Request — master (#27)
by Andrew
02:47
created

DaemonTrait::flagShutdown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace PHPFastCGI\FastCGIDaemon;
4
5
use PHPFastCGI\FastCGIDaemon\Exception\MemoryLimitException;
6
use PHPFastCGI\FastCGIDaemon\Exception\RequestLimitException;
7
use PHPFastCGI\FastCGIDaemon\Exception\ShutdownException;
8
use PHPFastCGI\FastCGIDaemon\Exception\TimeLimitException;
9
10
trait DaemonTrait
11
{
12
    /**
13
     * @var bool
14
     */
15
    private $isShutdown = false;
16
17
    /**
18
     * @var int
19
     */
20
    private $requestCount;
21
22
    /**
23
     * @var int
24
     */
25
    private $requestLimit;
26
27
    /**
28
     * @var int
29
     */
30
    private $memoryLimit;
31
32
    /**
33
     * Flags the daemon for shutting down.
34
     */
35
    public function flagShutdown()
36
    {
37
        $this->isShutdown = true;
38
    }
39
40
    /**
41
     * Loads to configuration from the daemon options and installs signal
42
     * handlers.
43
     *
44
     * @param DaemonOptions $daemonOptions
45
     */
46
    private function setupDaemon(DaemonOptions $daemonOptions)
47
    {
48
        $this->requestCount = 0;
49
        $this->requestLimit = $daemonOptions->getOption(DaemonOptions::REQUEST_LIMIT);
50
        $this->memoryLimit  = $daemonOptions->getOption(DaemonOptions::MEMORY_LIMIT);
51
52
        $timeLimit = $daemonOptions->getOption(DaemonOptions::TIME_LIMIT);
53
54
        if (DaemonOptions::NO_LIMIT !== $timeLimit) {
55
            pcntl_alarm($timeLimit);
56
        }
57
58
        $this->installSignalHandlers();
59
    }
60
61
    /**
62
     * Increments the request count.
63
     *
64
     * @param int $number The number of requests to increment the count by
65
     */
66
    private function incrementRequestCount($number)
67
    {
68
        $this->requestCount += $number;
69
    }
70
71
    /**
72
     * Installs a handler which throws a ShutdownException upon receiving a
73
     * SIGINT or a SIGALRM.
74
     *
75
     * @throws ShutdownException On receiving a SIGINT or SIGALRM
76
     */
77
    private function installSignalHandlers()
78
    {
79
        declare (ticks = 1);
80
81
        pcntl_signal(SIGINT, function () {
82
            throw new ShutdownException('Daemon shutdown requested (received SIGINT)');
83
        });
84
85
        pcntl_signal(SIGALRM, function () {
86
            throw new TimeLimitException('Daemon time limit reached (received SIGALRM)');
87
        });
88
    }
89
90
    /**
91
     * Checks the current PHP process against the limits specified in a daemon
92
     * options object. This function will also throw an exception if the daemon
93
     * has been flagged for shutdown.
94
     *
95
     * @throws ShutdownException When limits in the daemon options are exceeded
96
     */
97
    private function checkDaemonLimits()
98
    {
99
        if ($this->isShutdown) {
100
            throw new ShutdownException('Daemon flagged for shutdown');
101
        }
102
103
        pcntl_signal_dispatch();
104
105
        if (DaemonOptions::NO_LIMIT !== $this->requestLimit) {
106
            if ($this->requestLimit <= $this->requestCount) {
107
                throw new RequestLimitException('Daemon request limit reached ('.$this->requestCount.' of '.$this->requestLimit.')');
108
            }
109
        }
110
111
        if (DaemonOptions::NO_LIMIT !== $this->memoryLimit) {
112
            $memoryUsage = memory_get_usage(true);
113
114
            if ($this->memoryLimit <= $memoryUsage) {
115
                throw new MemoryLimitException('Daemon memory limit reached ('.$memoryUsage.' of '.$this->memoryLimit.' bytes)');
116
            }
117
        }
118
    }
119
}
120