Throttler   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 3
dl 0
loc 134
ccs 48
cts 48
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A push() 0 6 1
A pushAndStart() 0 6 1
B wait() 0 14 5
A getCompletedJobs() 0 4 1
A onJobWaiting() 0 4 1
A onJobRunning() 0 4 1
A onJobCompleted() 0 4 1
A tryStart() 0 18 3
A runningJobsIsFull() 0 4 1
1
<?php
2
3
namespace tomzx\Job;
4
5
use Evenement\EventEmitter;
6
7
class Throttler
8
{
9
    /**
10
     * @var int
11
     */
12
    private $maxCount;
13
    /**
14
     * @var \tomzx\Job\JobQueue
15
     */
16
    private $waitingJobs;
17
    /**
18
     * @var \tomzx\Job\JobQueue
19
     */
20
    private $runningJobs;
21
    /**
22
     * @var \tomzx\Job\JobQueue
23
     */
24
    private $completedJobs;
25
    /**
26
     * @var \tomzx\Job\JobQueue
27
     */
28
    private $eventEmitter;
29
30
    /**
31
     * @param int $maxCount
32
     * @param int $resolutionMicroSeconds
33
     */
34 8
    public function __construct(int $maxCount, int $resolutionMicroSeconds = 100000)
35
    {
36 8
        $this->maxCount = $maxCount;
37 8
        $this->waitingJobs = new JobQueue();
38 8
        $this->runningJobs = new JobQueue();
39 8
        $this->completedJobs = new JobQueue();
40 8
        $this->eventEmitter = new EventEmitter();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Evenement\EventEmitter() of type object<Evenement\EventEmitter> is incompatible with the declared type object<tomzx\Job\JobQueue> of property $eventEmitter.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
41 8
        $this->awaiter = new Awaiter($resolutionMicroSeconds);
0 ignored issues
show
Bug introduced by
The property awaiter does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
42 8
    }
43
44
    /**
45
     * @param \tomzx\Job\Job $job
46
     */
47 7
    public function push(Job $job)
48
    {
49 7
        $this->waitingJobs->push($job);
50
51 7
        $this->eventEmitter->emit('job.waiting', [$job]);
0 ignored issues
show
Bug introduced by
The method emit() does not seem to exist on object<tomzx\Job\JobQueue>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
52 7
    }
53
54
    /**
55
     * @param \tomzx\Job\Job $job
56
     */
57 2
    public function pushAndStart(Job $job)
58
    {
59 2
        $this->push($job);
60
61 2
        $this->tryStart();
62 2
    }
63
64 6
    public function wait()
65
    {
66 6
        while ( ! $this->runningJobs->isEmpty() || ! $this->waitingJobs->isEmpty()) {
67 5
            $this->tryStart();
68
69 5
            if ($this->runningJobsIsFull() || $this->waitingJobs->isEmpty()) {
70 5
                $completedJob = $this->awaiter->any($this->runningJobs);
71 5
                $this->runningJobs->remove($completedJob);
72 5
                $this->completedJobs->push($completedJob);
73
74 5
                $this->eventEmitter->emit('job.completed', [$completedJob]);
0 ignored issues
show
Bug introduced by
The method emit() does not seem to exist on object<tomzx\Job\JobQueue>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
75
            }
76
        }
77 6
    }
78
79
    /**
80
     * @return \tomzx\Job\JobQueue
81
     */
82 3
    public function getCompletedJobs()
83
    {
84 3
        return $this->completedJobs;
85
    }
86
87
    /**
88
     * @param callable $callback
89
     */
90 1
    public function onJobWaiting(callable $callback)
91
    {
92 1
        $this->eventEmitter->on('job.waiting', $callback);
0 ignored issues
show
Bug introduced by
The method on() does not seem to exist on object<tomzx\Job\JobQueue>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93 1
    }
94
95
    /**
96
     * @param callable $callback
97
     */
98 1
    public function onJobRunning(callable $callback)
99
    {
100 1
        $this->eventEmitter->on('job.running', $callback);
0 ignored issues
show
Bug introduced by
The method on() does not seem to exist on object<tomzx\Job\JobQueue>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
101 1
    }
102
103
    /**
104
     * @param callable $callback
105
     */
106 1
    public function onJobCompleted(callable $callback)
107
    {
108 1
        $this->eventEmitter->on('job.completed', $callback);
0 ignored issues
show
Bug introduced by
The method on() does not seem to exist on object<tomzx\Job\JobQueue>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
109 1
    }
110
111
    /**
112
     * @return \tomzx\Job\Job|void
113
     */
114 6
    private function tryStart()
115
    {
116 6
        if ($this->waitingJobs->isEmpty()) {
117 1
            return;
118
        }
119
120 6
        if ($this->runningJobsIsFull()) {
121 1
            return;
122
        }
123
124 6
        $job = $this->waitingJobs->pop();
125 6
        $job->handle();
126 6
        $this->runningJobs->push($job);
0 ignored issues
show
Bug introduced by
It seems like $job defined by $this->waitingJobs->pop() on line 124 can be null; however, tomzx\Job\JobQueue::push() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
127
128 6
        $this->eventEmitter->emit('job.running', [$job]);
0 ignored issues
show
Bug introduced by
The method emit() does not seem to exist on object<tomzx\Job\JobQueue>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
129
130 6
        return $job;
131
    }
132
133
    /**
134
     * @return bool
135
     */
136 6
    private function runningJobsIsFull()
137
    {
138 6
        return $this->runningJobs->count() >= $this->maxCount;
139
    }
140
}
141