Completed
Branch 0.4-dev (54e67b)
by Evgenij
02:52
created

AbstractOobHandler   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
c 1
b 0
f 0
lcom 1
cbo 5
dl 0
loc 102
ccs 29
cts 29
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getInvokeState() 0 6 2
B handleOobData() 0 27 2
A handle() 0 19 3
handleOperation() 0 5 ?
1
<?php
2
/**
3
 * Async sockets
4
 *
5
 * @copyright Copyright (c) 2015-2016, 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\ReadEvent;
13
use AsyncSockets\Frame\RawFramePicker;
14
use AsyncSockets\Operation\OperationInterface;
15
use AsyncSockets\RequestExecutor\EventHandlerInterface;
16
use AsyncSockets\RequestExecutor\IoHandlerInterface;
17
use AsyncSockets\RequestExecutor\Metadata\RequestDescriptor;
18
use AsyncSockets\RequestExecutor\RequestExecutorInterface;
19
20
/**
21
 * Class AbstractOobHandler
22
 */
23
abstract class AbstractOobHandler implements IoHandlerInterface
24
{
25
    /**
26
     * Operation to descriptor state map
27
     *
28
     * @var array
29
     */
30
    private static $stateMap = [
31
        OperationInterface::OPERATION_READ  => RequestDescriptor::RDS_READ,
32
        OperationInterface::OPERATION_WRITE => RequestDescriptor::RDS_WRITE,
33
    ];
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 108
    final public function handle(
39
        RequestDescriptor $descriptor,
40
        RequestExecutorInterface $executor,
41
        EventHandlerInterface $eventHandler
42
    ) {
43 108
        $result = $this->handleOobData($descriptor, $executor, $eventHandler);
44 108
        if ($result) {
45 6
            return $result;
46
        }
47
48 103
        $state = $this->getInvokeState($descriptor->getOperation());
49 103
        if ($descriptor->hasState($state)) {
50 98
            $descriptor->clearState($state);
51
52 98
            $result = $this->handleOperation($descriptor, $executor, $eventHandler);
53 57
        }
54
55 62
        return $result;
56
    }
57
58
    /**
59
     * Process given operation
60
     *
61
     * @param RequestDescriptor        $descriptor Request descriptor
62
     * @param RequestExecutorInterface $executor Executor, processing operation
63
     * @param EventHandlerInterface    $eventHandler Event handler for this operation
64
     *
65
     * @return OperationInterface|null Next operation to pass in socket. Return null,
66
     *      if next operation is not required. Return $operation parameter, if operation is not completed yet
67
     */
68
    abstract protected function handleOperation(
69
        RequestDescriptor $descriptor,
70
        RequestExecutorInterface $executor,
71
        EventHandlerInterface $eventHandler
72
    );
73
74
    /**
75
     * Return state which should invoke this operation
76
     *
77
     * @param OperationInterface $operation Operation object
78
     *
79
     * @return int RequestDescriptor::RDS_* constant
80
     */
81 103
    private function getInvokeState(OperationInterface $operation)
82
    {
83 103
        $type = $operation->getType();
84
85 103
        return isset(self::$stateMap[$type]) ? self::$stateMap[$type] : 0;
86
    }
87
88
    /**
89
     * Handle OOB data
90
     *
91
     * @param RequestDescriptor        $descriptor Request descriptor
92
     * @param RequestExecutorInterface $executor Executor, processing operation
93
     * @param EventHandlerInterface    $eventHandler Event handler for this operation
94
     *
95
     * @return OperationInterface|null Operation to return to user or null to continue normal processing
96
     */
97 108
    private function handleOobData(
98
        RequestDescriptor $descriptor,
99
        RequestExecutorInterface $executor,
100
        EventHandlerInterface $eventHandler
101
    ) {
102 108
        if (!$descriptor->hasState(RequestDescriptor::RDS_OOB)) {
103 98
            return null;
104
        }
105
106 10
        $descriptor->clearState(RequestDescriptor::RDS_OOB);
107
108 10
        $picker = new RawFramePicker();
109 10
        $socket = $descriptor->getSocket();
110 10
        $meta   = $descriptor->getMetadata();
111 10
        $frame  = $socket->read($picker, true);
112 10
        $event  = new ReadEvent(
113 10
            $executor,
114 10
            $socket,
115 10
            $meta[ RequestExecutorInterface::META_USER_CONTEXT ],
116 10
            $frame,
117
            true
118 10
        );
119
120 10
        $eventHandler->invokeEvent($event);
121
122 10
        return $event->getNextOperation();
123
    }
124
}
125