Completed
Branch 0.4-dev (97f287)
by Evgenij
02:20
created

RequestDescriptor::invokeEvent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
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
use AsyncSockets\Event\Event;
13
use AsyncSockets\Operation\OperationInterface;
14
use AsyncSockets\RequestExecutor\EventHandlerInterface;
15
use AsyncSockets\RequestExecutor\RequestExecutorInterface;
16
use AsyncSockets\Socket\PersistentClientSocket;
17
use AsyncSockets\Socket\SocketInterface;
18
use AsyncSockets\Socket\StreamResourceInterface;
19
20
/**
21
 * Class RequestDescriptor
22
 */
23
class RequestDescriptor implements StreamResourceInterface, EventHandlerInterface
24
{
25
    /**
26
     * This descriptor is ready for reading
27
     */
28
    const RDS_READ = 0x0001;
29
30
    /**
31
     * This descriptor is ready for writing
32
     */
33
    const RDS_WRITE = 0x0002;
34
35
    /**
36
     * This descriptor is has OOB data
37
     */
38
    const RDS_OOB = 0x0004;
39
40
    /**
41
     * Minimum transfer rate counter for receiving data
42
     */
43
    const COUNTER_RECV_MIN_RATE = 'recv_speed_rate_counter';
44
45
    /**
46
     * Minimum transfer rate counter for sending data
47
     */
48
    const COUNTER_SEND_MIN_RATE = 'send_speed_rate_counter';
49
50
    /**
51
     * Socket for this operation
52
     *
53
     * @var SocketInterface
54
     */
55
    private $socket;
56
57
    /**
58
     * Key-value pairs with meta information
59
     *
60
     * @var array
61
     */
62
    private $metadata;
63
64
    /**
65
     * Event handler object
66
     *
67
     * @var EventHandlerInterface
68
     */
69
    private $handlers;
70
71
    /**
72
     * Flag whether this socket request is running
73
     *
74
     * @var bool
75
     */
76
    private $isRunning;
77
78
    /**
79
     * Operation to perform on socket
80
     *
81
     * @var OperationInterface
82
     */
83
    private $operation;
84
85
    /**
86
     * Flag if this socket is postponed
87
     *
88
     * @var bool
89
     */
90
    private $isPostponed = false;
91
92
    /**
93
     * Set of state flags: RDS_* consts
94
     *
95
     * @var int
96
     */
97
    private $state = 0;
98
99
    /**
100
     * Array of counters
101
     *
102
     * @var SpeedRateCounter[]
103
     */
104
    private $counters;
105
106
    /**
107
     * RequestDescriptor constructor.
108
     *
109
     * @param SocketInterface       $socket Socket object
110
     * @param OperationInterface    $operation Operation to perform on socket
111
     * @param array                 $metadata Metadata
112
     * @param EventHandlerInterface $handlers Handlers for this socket
113
     */
114 177
    public function __construct(
115
        SocketInterface $socket,
116
        OperationInterface $operation,
117
        array $metadata,
118
        EventHandlerInterface $handlers = null
119
    ) {
120 177
        $this->socket    = $socket;
121 177
        $this->operation = $operation;
122 177
        $this->metadata  = $metadata;
123 177
        $this->handlers  = $handlers;
124 177
        $this->counters  = [];
125 177
        $this->initialize();
126 177
    }
127
128
    /**
129
     * Initialize data before request
130
     *
131
     * @return void
132
     */
133 177
    public function initialize()
134
    {
135 177
        $this->isRunning = false;
136 177
    }
137
138
    /**
139
     * Return Operation
140
     *
141
     * @return OperationInterface
142
     */
143 109
    public function getOperation()
144
    {
145 109
        return $this->operation;
146
    }
147
148
    /**
149
     * Sets Operation
150
     *
151
     * @param OperationInterface $operation New operation
152
     *
153
     * @return void
154
     */
155 51
    public function setOperation(OperationInterface $operation)
156
    {
157 51
        $this->operation = $operation;
158 51
    }
159
160
    /**
161
     * Return flag whether request is running
162
     *
163
     * @return boolean
164
     */
165 137
    public function isRunning()
166
    {
167 137
        return $this->isRunning;
168
    }
169
170
    /**
171
     * Sets running flag
172
     *
173
     * @param boolean $isRunning New value for IsRunning
174
     *
175
     * @return void
176
     */
177 108
    public function setRunning($isRunning)
178
    {
179 108
        $this->isRunning = $isRunning;
180 108
    }
181
182
    /**
183
     * Return Socket
184
     *
185
     * @return SocketInterface
186
     */
187 136
    public function getSocket()
188
    {
189 136
        return $this->socket;
190
    }
191
192
    /** {@inheritdoc} */
193 53
    public function getStreamResource()
194
    {
195 53
        return $this->socket->getStreamResource();
196
    }
197
198
    /**
199
     * Return key-value array with metadata
200
     *
201
     * @return array
202
     */
203 163
    public function getMetadata()
204
    {
205 163
        return $this->metadata;
206
    }
207
208
    /**
209
     * Set metadata for given socket
210
     *
211
     * @param string|array    $key Either string or key-value array of metadata. If string, then value must be
212
     *                             passed in third argument, if array, then third argument will be ignored
213
     * @param mixed           $value Value for key or null, if $key is array
214
     *
215
     * @return void
216
     */
217 159
    public function setMetadata($key, $value = null)
218
    {
219 159
        if (!is_array($key)) {
220 140
            $this->metadata[$key] = $value;
221 140
        } else {
222 29
            $this->metadata = array_merge(
223 29
                $this->metadata,
224
                $key
225 29
            );
226
        }
227 159
    }
228
229
    /** {@inheritdoc} */
230 135
    public function invokeEvent(Event $event)
231
    {
232 135
        if ($this->handlers) {
233 21
            $this->handlers->invokeEvent($event);
234 17
        }
235 131
    }
236
237
    /**
238
     * Completes processing this socket in event loop, but keep this socket connection opened. Applicable
239
     * only to persistent sockets, all other socket types are ignored by this method.
240
     *
241
     * @return void
242
     */
243 6
    public function postpone()
244
    {
245 6
        if (!($this->socket instanceof PersistentClientSocket)) {
246 5
            return;
247
        }
248
249 1
        $this->isPostponed = true;
250 1
    }
251
252
    /**
253
     * Return true, if this socket shouldn't be processed by executor engine
254
     *
255
     * @return bool
256
     */
257 122
    public function isPostponed()
258
    {
259 122
        return $this->isPostponed;
260
    }
261
262
    /**
263
     * Return true if descriptor has given state
264
     *
265
     * @param int $state State to check, set of RDS_* consts
266
     *
267
     * @return bool
268
     */
269 111
    public function hasState($state)
270
    {
271 111
        return (bool) ($this->state & $state);
272
    }
273
274
    /**
275
     * Sets one state into an object
276
     *
277
     * @param int $state State to set, set of RDS_* consts
278
     *
279
     * @return void
280
     */
281 129
    public function setState($state)
282
    {
283 129
        $this->state |= $state;
284 129
    }
285
286
    /**
287
     * Clears given state in object
288
     *
289
     * @param int $state State to clear, set of RDS_* consts
290
     *
291
     * @return void
292
     */
293 111
    public function clearState($state)
294
    {
295 111
        $this->state &= ~$state;
296 111
    }
297
298
    /**
299
     * Registers counter in this descriptor
300
     *
301
     * @param string           $name SpeedRateCounter name for retrieving
302
     * @param SpeedRateCounter $counter A counter object
303
     *
304
     * @return void
305
     */
306 80
    public function registerCounter($name, SpeedRateCounter $counter)
307
    {
308 80
        if (!isset($this->counters[$name])) {
309 80
            $this->counters[$name] = $counter;
310 80
        }
311 80
    }
312
313
    /**
314
     * Return counter by given name
315
     *
316
     * @param string $name SpeedRateCounter name
317
     *
318
     * @return SpeedRateCounter|null
319
     */
320 80
    public function getCounter($name)
321
    {
322 80
        return isset($this->counters[$name]) ? $this->counters[$name] : null;
323
    }
324
325
    /**
326
     * Resets counter with given name
327
     *
328
     * @param string $name Counter name
329
     *
330
     * @return void
331
     */
332 80
    public function resetCounter($name)
333
    {
334 80
        $counter = $this->getCounter($name);
335 80
        if (!$counter) {
336 79
            return;
337
        }
338
339
        $resetMetadata = [
340 1
            self::COUNTER_RECV_MIN_RATE => [
341 1
                RequestExecutorInterface::META_RECEIVE_SPEED => 0,
342 1
            ],
343 1
            self::COUNTER_SEND_MIN_RATE => [
344 1
                RequestExecutorInterface::META_SEND_SPEED => 0,
345 1
            ],
346 1
        ];
347
348 1
        $counter->reset();
349 1
        if (isset($resetMetadata[$name])) {
350 1
            $this->setMetadata($resetMetadata[$name]);
351 1
        }
352 1
    }
353
}
354