Completed
Branch 0.4-dev (50fa9b)
by Evgenij
02:41
created

ReadIoHandler   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 96.43%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 8
dl 0
loc 123
ccs 54
cts 56
cp 0.9643
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A supports() 0 4 1
B handleOperation() 0 61 5
A appendReadBytes() 0 4 1
A isEof() 0 4 1
A pickUpData() 0 5 1
A createFrame() 0 4 1
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\Pipeline;
11
12
use AsyncSockets\Event\AcceptEvent;
13
use AsyncSockets\Event\ReadEvent;
14
use AsyncSockets\Exception\AcceptException;
15
use AsyncSockets\Frame\AcceptedFrame;
16
use AsyncSockets\Frame\FramePickerInterface;
17
use AsyncSockets\Frame\PartialFrame;
18
use AsyncSockets\Operation\OperationInterface;
19
use AsyncSockets\Operation\ReadOperation;
20
use AsyncSockets\RequestExecutor\EventHandlerInterface;
21
use AsyncSockets\RequestExecutor\ExecutionContext;
22
use AsyncSockets\RequestExecutor\Metadata\RequestDescriptor;
23
use AsyncSockets\RequestExecutor\RequestExecutorInterface;
24
25
/**
26
 * Class ReadIoHandler
27
 */
28
class ReadIoHandler extends AbstractOobHandler implements FramePickerInterface
29
{
30
    /**
31
     * Amount of bytes read by last operation
32
     *
33
     * @var int
34
     */
35
    private $bytesRead;
36
37
    /**
38
     * Actual frame picker
39
     *
40
     * @var FramePickerInterface
41
     */
42
    private $realFramePicker;
43
44
    /** {@inheritdoc} */
45 83
    public function supports(OperationInterface $operation)
46
    {
47 83
        return $operation instanceof ReadOperation;
48
    }
49
50
    /** {@inheritdoc} */
51 51
    protected function handleOperation(
52
        RequestDescriptor $descriptor,
53
        RequestExecutorInterface $executor,
54
        EventHandlerInterface $eventHandler,
55
        ExecutionContext $executionContext
56
    ) {
57
        /** @var ReadOperation $operation */
58 51
        $operation = $descriptor->getOperation();
59 51
        $socket    = $descriptor->getSocket();
60
61 51
        $meta    = $executor->socketBag()->getSocketMetaData($socket);
62 51
        $context = $meta[RequestExecutorInterface::META_USER_CONTEXT];
63 51
        $result  = null;
64
65 51
        $this->bytesRead       = 0;
66 51
        $this->realFramePicker = $operation->getFramePicker();
67
68
        try {
69 51
            $response = $socket->read($this);
70 47
            switch (true) {
71 47
                case $response instanceof PartialFrame:
72 2
                    $result = $operation;
73 2
                    break;
74 45
                case $response instanceof AcceptedFrame:
75 5
                    $event = new AcceptEvent(
76 5
                        $executor,
77 5
                        $socket,
78 5
                        $context,
79 5
                        $response->getClientSocket(),
80 5
                        $response->getRemoteAddress()
81 5
                    );
82
83 5
                    $eventHandler->invokeEvent($event, $executor, $socket, $executionContext);
84 1
                    $result = new ReadOperation();
85 1
                    break;
86 40
                default:
87 40
                    $event = new ReadEvent(
88 40
                        $executor,
89 40
                        $socket,
90 40
                        $context,
91 40
                        $response,
92
                        false
93 40
                    );
94
95 40
                    $eventHandler->invokeEvent($event, $executor, $socket, $executionContext);
96 25
                    $result = $event->getNextOperation();
97 25
                    break;
98 40
            }
99 51
        } catch (AcceptException $e) {
100 1
            $result = new ReadOperation();
101 23
        } catch (\Exception $e) {
102 22
            $this->appendReadBytes($descriptor, $this->bytesRead);
103 22
            unset($this->realFramePicker, $this->bytesRead);
104 22
            throw $e;
105
        }
106
107 29
        $this->appendReadBytes($descriptor, $this->bytesRead);
108 28
        unset($this->realFramePicker, $this->bytesRead);
109
110 28
        return $result;
111
    }
112
113
    /**
114
     * Append given mount of read bytes to descriptor
115
     *
116
     * @param RequestDescriptor $descriptor The descriptor
117
     * @param int               $bytesRead Amount of read bytes
118
     *
119
     * @return void
120
     */
121 51
    private function appendReadBytes(RequestDescriptor $descriptor, $bytesRead)
122
    {
123 51
        $this->handleTransferCounter(RequestDescriptor::COUNTER_RECV_MIN_RATE, $descriptor, $bytesRead);
124 50
    }
125
126
    /**
127
     * {@inheritDoc}
128
     */
129
    public function isEof()
130
    {
131
        return $this->realFramePicker->isEof();
132
    }
133
134
    /**
135
     * {@inheritDoc}
136
     */
137 3
    public function pickUpData($chunk, $remoteAddress)
138
    {
139 3
        $this->bytesRead += strlen($chunk);
140 3
        return $this->realFramePicker->pickUpData($chunk, $remoteAddress);
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146 1
    public function createFrame()
147
    {
148 1
        return $this->realFramePicker->createFrame();
149
    }
150
}
151