Completed
Branch 0.4-dev (dcd04a)
by Evgenij
02:34
created

ReadIoHandler   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 95.56%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 8
dl 0
loc 122
ccs 43
cts 45
cp 0.9556
rs 10
c 0
b 0
f 0

6 Methods

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