Completed
Branch master (1d1574)
by Evgenij
18:38
created

AsyncSocketFactory::createSocket()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 19
ccs 14
cts 14
cp 1
rs 8.8571
cc 6
eloc 15
nc 10
nop 2
crap 6
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
11
namespace AsyncSockets\Socket;
12
13
use AsyncSockets\Configuration\Configuration;
14
use AsyncSockets\RequestExecutor\LibEventRequestExecutor;
15
use AsyncSockets\RequestExecutor\NativeRequestExecutor;
16
use AsyncSockets\RequestExecutor\Pipeline\BaseStageFactory;
17
use AsyncSockets\RequestExecutor\Pipeline\PipelineFactory;
18
use AsyncSockets\RequestExecutor\RequestExecutorInterface;
19
20
/**
21
 * Class AsyncSocketFactory
22
 *
23
 * @api
24
 */
25
class AsyncSocketFactory
26
{
27
    /**
28
     * Create client socket
29
     */
30
    const SOCKET_CLIENT = 'client';
31
32
    /**
33
     * Create server socket
34
     */
35
    const SOCKET_SERVER = 'server';
36
37
    /**
38
     * Boolean flag whether it is persistent socket, applicable only for SOCKET_CLIENT type
39
     */
40
    const SOCKET_OPTION_IS_PERSISTENT = 'soIsPersistent';
41
42
    /**
43
     * Key in php storage to allow multiple persistent connections to the same host [a-zA-Z0-9_-]
44
     */
45
    const SOCKET_OPTION_PERSISTENT_KEY = 'soPersistentKey';
46
47
    /**
48
     * Default configuration for this factory
49
     *
50
     * @var Configuration
51
     */
52
    private $configuration;
53
54
    /**
55
     * AsyncSocketFactory constructor.
56
     *
57
     * @param Configuration $configuration Default configuration for this factory
58
     */
59 7
    public function __construct(Configuration $configuration = null)
60
    {
61 7
        $this->configuration = $configuration ?: new Configuration();
62 7
    }
63
64
    /**
65
     * Create socket client
66
     *
67
     * @param string      $type Socket type to create, one of SOCKET_* consts
68
     * @param array       $options  $flags Flags with socket settings, see SOCKET_OPTION_* consts
69
     *
70
     * @return SocketInterface
71
     * @api
72
     */
73 4
    public function createSocket($type = self::SOCKET_CLIENT, array $options = [])
74
    {
75
        switch ($type) {
76 4
            case self::SOCKET_CLIENT:
77 2
                $isPersistent  = isset($options[ self::SOCKET_OPTION_IS_PERSISTENT ]) &&
78 2
                                 $options[ self::SOCKET_OPTION_IS_PERSISTENT ];
79 2
                $persistentKey = isset($options[ self::SOCKET_OPTION_PERSISTENT_KEY ]) ?
80 2
                    $options[ self::SOCKET_OPTION_PERSISTENT_KEY ] :
81 2
                    null;
82
83
                return $isPersistent ?
84 2
                    new PersistentClientSocket($persistentKey) :
85 2
                    new ClientSocket();
86 2
            case self::SOCKET_SERVER:
87 1
                return new ServerSocket();
88 1
            default:
89 1
                throw new \InvalidArgumentException("Unexpected type {$type} used in " . __FUNCTION__);
90 1
        }
91
    }
92
93
    /**
94
     * Create RequestExecutor object
95
     *
96
     * @return RequestExecutorInterface
97
     *
98
     * @api
99
     */
100 3
    public function createRequestExecutor()
101
    {
102 3
        foreach ($this->configuration->getPreferredEngines() as $engine) {
103
            switch ($engine) {
104 3
                case 'libevent':
105 2
                    if (extension_loaded('libevent')) {
106 1
                        return new LibEventRequestExecutor(new BaseStageFactory(), $this->configuration);
107
                    }
108 1
                    break;
109 2
                case 'native':
110 1
                    return new NativeRequestExecutor(
111 1
                        new PipelineFactory(
112 1
                            new BaseStageFactory()
113 1
                        ),
114 1
                        $this->configuration
115 1
                    );
116
            }
117 2
        }
118
119 1
        throw new \InvalidArgumentException(
120
            'Provided configuration does not contain any supported RequestExecutor engine.'
121 1
        );
122
    }
123
}
124