Completed
Branch 0.4-dev (79cc15)
by Evgenij
03:32
created

SpeedRateCounter::measure()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * Async sockets
4
 *
5
 * @copyright Copyright (c) 2015-2017, Efimov Evgenij <[email protected]>
6
 *
7
 * This source file is subject to the MIT license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
namespace AsyncSockets\RequestExecutor\Metadata;
11
12
/**
13
 * Class SpeedRateCounter
14
 */
15
class SpeedRateCounter
16
{
17
    /**
18
     * Amount of processed bytes
19
     *
20
     * @var int
21
     */
22
    private $totalBytesProcessed;
23
24
    /**
25
     * Time when request is started
26
     *
27
     * @var int
28
     */
29
    private $initialTime;
30
31
    /**
32
     * Time of last measurement
33
     *
34
     * @var int
35
     */
36
    private $currentTime;
37
38
    /**
39
     * Time when speed felt below minimal
40
     *
41
     * @var int
42
     */
43
    private $slowStartTime;
44
45
    /**
46
     * Minimum allowed speed in bytes per second
47
     *
48
     * @var float
49
     */
50
    private $minSpeed;
51
52
    /**
53
     * Maximum duration of minimum speed in seconds
54
     *
55
     * @var float
56
     */
57
    private $maxDuration;
58
59
    /**
60
     * Current speed
61
     *
62
     * @var double
63
     */
64
    private $currentSpeed;
65
66
    /**
67
     * SpeedRateCounter constructor.
68
     *
69
     * @param double $minSpeed Minimum allowed speed in bytes per second
70
     * @param double $maxDuration Maximum duration of minimum speed in seconds
71
     */
72 39
    public function __construct($minSpeed, $maxDuration)
73
    {
74 39
        $this->minSpeed    = $minSpeed;
75 39
        $this->maxDuration = $maxDuration;
76 39
        $this->reset();
77 39
    }
78
79
    /**
80
     * Resets this counter
81
     *
82
     * @return void
83
     */
84 39
    public function reset()
85
    {
86 39
        $this->initialTime         = null;
87 39
        $this->currentTime         = null;
88 39
        $this->totalBytesProcessed = 0;
89 39
        $this->currentSpeed        = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $currentSpeed was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
90 39
        $this->slowStartTime       = null;
91 39
    }
92
93
    /**
94
     * Process next measurement
95
     *
96
     * @param double $time Time in seconds
97
     * @param double $value Amount of received data in bytes
98
     *
99
     * @return void
100
     * @throws \OverflowException When speed is slower then desired
101
     */
102 39
    public function advance($time, $value)
103
    {
104 39
        $this->measure($time, $value);
105 39
        $this->currentSpeed = $this->getAverageSpeed();
0 ignored issues
show
Documentation Bug introduced by
The property $currentSpeed was declared of type double, but $this->getAverageSpeed() is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
106 39
        if ($this->minSpeed === null || $this->maxDuration === null || $this->currentSpeed === null) {
107 29
            return;
108
        }
109
110 10
        if ($this->currentSpeed < $this->minSpeed) {
111 10
            $this->slowStartTime = $this->slowStartTime !== null ? $this->slowStartTime : $time;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->slowStartTime !==...->slowStartTime : $time can also be of type double. However, the property $slowStartTime is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
112
113 10
            if ($time - $this->slowStartTime > $this->maxDuration) {
114 10
                throw new \OverflowException();
115
            }
116
        } else {
117 3
            $this->slowStartTime = null;
118
        }
119 10
    }
120
121
    /**
122
     * Adds measure for counter
123
     *
124
     * @param double $time Time for given value in absolute timestamp
125
     * @param double $value A value
126
     *
127
     * @return void
128
     */
129 39
    private function measure($time, $value)
130
    {
131 39
        if ($this->initialTime === null) {
132 39
            $this->initialTime = $time;
0 ignored issues
show
Documentation Bug introduced by
The property $initialTime was declared of type integer, but $time is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
133
        } else {
134 33
            $this->currentTime = $time;
0 ignored issues
show
Documentation Bug introduced by
The property $currentTime was declared of type integer, but $time is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
135
        }
136
137 39
        $this->totalBytesProcessed += $value;
138 39
    }
139
140
    /**
141
     * Return average speed for measurements
142
     *
143
     * @return double|null
144
     */
145 39
    private function getAverageSpeed()
146
    {
147 39
        $timeElapsed = $this->currentTime - $this->initialTime;
148
149 39
        return $timeElapsed >= 1 ? ($this->totalBytesProcessed / $timeElapsed) : 0;
150
    }
151
152
    /**
153
     * Return current speed in bytes per seconds
154
     *
155
     * @return float
156
     */
157 38
    public function getCurrentSpeed()
158
    {
159 38
        return $this->getAverageSpeed();
160
    }
161
162
    /**
163
     * Return duration of current slow speed
164
     *
165
     * @return int
166
     */
167 10
    public function getCurrentDuration()
168
    {
169 10
        return $this->slowStartTime !== null ? $this->currentTime - $this->slowStartTime : 0;
170
    }
171
}
172