InMemoryRules::addRule()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace AsyncPHP\Doorman\Rules;
4
5
use AsyncPHP\Doorman\Profile;
6
use AsyncPHP\Doorman\Rule;
7
use AsyncPHP\Doorman\Rules;
8
use AsyncPHP\Doorman\Task;
9
10
final class InMemoryRules implements Rules
11
{
12
    /**
13
     * @var Rule[]
14
     */
15
    private $rules = [];
16
17
    /**
18
     * @inheritdoc
19
     *
20
     * @param Rule $rule
21
     *
22
     * @return $this
23
     */
24 2
    public function addRule(Rule $rule)
25
    {
26 2
        $hash = spl_object_hash($rule);
27
28 2
        $this->rules[$hash] = $rule;
29
30 2
        return $this;
31
    }
32
33
    /**
34
     * @inheritdoc
35
     *
36
     * @param Rule $rule
37
     *
38
     * @return $this
39
     */
40 2
    public function removeRule(Rule $rule)
41
    {
42 2
        $hash = spl_object_hash($rule);
43
44 2
        if (isset($this->rules[$hash])) {
45 2
            unset($this->rules[$hash]);
46 2
        }
47
48 2
        return $this;
49
    }
50
51
    /**
52
     * @inheritdoc
53
     *
54
     * @param Task $task
55
     * @param Profile $profile
56
     *
57
     * @return bool
58
     */
59 2
    public function canRunTask(Task $task, Profile $profile)
60
    {
61 2
        $rules = $this->getRulesForTask($task);
62
63 2
        if (count($rules) === 0) {
64 1
            return true;
65
        }
66
67 2
        foreach ($rules as $rule) {
68 2
            if ($rule->getProcesses() === null) {
69 1
                continue;
70
            }
71
72 2
            if (($rule->getHandler() === null || $rule->getHandler() === $task->getHandler()) && ($this->hasTooManyProcessesRunning($rule, $profile) || $this->hasTooManySiblingProcessesRunning($rule, $profile))) {
73 2
                return false;
74
            }
75 1
        }
76
77 1
        return true;
78
    }
79
80
    /**
81
     * Gets all the rules that apply to a task.
82
     *
83
     * @param Task $task
84
     *
85
     * @return Rule[]
86
     */
87
    private function getRulesForTask(Task $task)
88
    {
89 2
        return array_filter($this->rules, function (Rule $rule) use ($task) {
90 2
            return $rule->getHandler() === null || $rule->getHandler() === $task->getHandler();
91 2
        });
92
    }
93
94
    /**
95
     * Checks whether there are too many processes running to start a new one.
96
     *
97
     * @param Rule $rule
98
     * @param Profile $profile
99
     *
100
     * @return bool
101
     */
102 2
    private function hasTooManyProcessesRunning(Rule $rule, Profile $profile)
103
    {
104 2
        return $this->withinConstraints($rule, $profile) && count($profile->getProcesses()) >= $rule->getProcesses();
105
    }
106
107
    /**
108
     * Checks whether the current profile is within the constraints of a rule.
109
     *
110
     * @param Rule $rule
111
     * @param Profile $profile
112
     *
113
     * @return bool
114
     */
115 2
    private function withinConstraints(Rule $rule, Profile $profile)
116
    {
117 2
        return $this->withinProcessorConstraints($rule, $profile) || $this->withinMemoryConstraints($rule, $profile);
118
    }
119
120
    /**
121
     * Checks whether the current profile is within the processor constraints of a rule.
122
     *
123
     * @param Rule $rule
124
     * @param Profile $profile
125
     *
126
     * @return bool
127
     */
128 2
    private function withinProcessorConstraints(Rule $rule, Profile $profile)
129
    {
130 2
        if ($rule->getMinimumProcessorUsage() !== null && $rule->getMaximumProcessorUsage() !== null) {
131 2
            return $profile->getProcessorLoad() >= $rule->getMinimumProcessorUsage() && $profile->getProcessorLoad() <= $rule->getMaximumProcessorUsage();
132
        }
133
134 1
        return false;
135
    }
136
137
    /**
138
     * Checks whether the current profile is within the memory constraints of a rule.
139
     *
140
     * @param Rule $rule
141
     * @param Profile $profile
142
     *
143
     * @return bool
144
     */
145 1
    private function withinMemoryConstraints(Rule $rule, Profile $profile)
146
    {
147 1
        if ($rule->getMinimumMemoryUsage() !== null && $rule->getMaximumMemoryUsage() !== null) {
148 1
            return $profile->getMemoryLoad() >= $rule->getMinimumMemoryUsage() && $profile->getMemoryLoad() <= $rule->getMaximumMemoryUsage();
149
        }
150
151 1
        return false;
152
    }
153
154
    /**
155
     * Checks whether there are too many sibling processes running to start a new one.
156
     *
157
     * @param Rule $rule
158
     * @param Profile $profile
159
     *
160
     * @return bool
161
     */
162 2
    private function hasTooManySiblingProcessesRunning(Rule $rule, Profile $profile)
163
    {
164 2
        return $this->withinSiblingConstraints($rule, $profile) && count($profile->getSiblingProcesses()) >= $rule->getProcesses();
165
    }
166
167
    /**
168
     * Checks whether the profile or sibling processes is within the constraints of a rule.
169
     *
170
     * @param Rule $rule
171
     * @param Profile $profile
172
     *
173
     * @return bool
174
     */
175 2
    private function withinSiblingConstraints(Rule $rule, Profile $profile)
176
    {
177 2
        return $this->withinSiblingProcessorConstraints($rule, $profile) || $this->withinSiblingMemoryConstraints($rule, $profile);
178
    }
179
180
    /**
181
     * Checks whether the profile or sibling processes is within the processor constraints of a
182
     * rule.
183
     *
184
     * @param Rule $rule
185
     * @param Profile $profile
186
     *
187
     * @return bool
188
     */
189 2
    private function withinSiblingProcessorConstraints(Rule $rule, Profile $profile)
190
    {
191 2
        if ($rule->getMinimumSiblingProcessorUsage() !== null && $rule->getMaximumSiblingProcessorUsage() !== null) {
192 1
            return $profile->getSiblingProcessorLoad() >= $rule->getMinimumSiblingProcessorUsage() && $profile->getSiblingProcessorLoad() <= $rule->getMaximumSiblingProcessorUsage();
193
        }
194
195 2
        return false;
196
    }
197
198
    /**
199
     * Checks whether the profile or sibling processes is within the memory constraints of a rule.
200
     *
201
     * @param Rule $rule
202
     * @param Profile $profile
203
     *
204
     * @return bool
205
     */
206 2
    private function withinSiblingMemoryConstraints(Rule $rule, Profile $profile)
207
    {
208 2
        if ($rule->getMinimumSiblingMemoryUsage() !== null && $rule->getMaximumSiblingMemoryUsage() !== null) {
209 1
            return $profile->getSiblingMemoryLoad() >= $rule->getMinimumSiblingMemoryUsage() && $profile->getSiblingMemoryLoad() <= $rule->getMaximumSiblingMemoryUsage();
210
        }
211
212 1
        return false;
213
    }
214
}
215