Completed
Push — master ( 59df9b...8cdd26 )
by Christopher
03:30
created

DoormanConnector::connectDoorman()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 62
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 62
ccs 0
cts 48
cp 0
rs 9.4745
cc 3
eloc 38
nc 3
nop 1
crap 12

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace AsyncPHP\Icicle\Database\Connector;
4
5
use AsyncPHP\Doorman\Manager;
6
use AsyncPHP\Doorman\Manager\ProcessManager;
7
use AsyncPHP\Doorman\Task\ProcessCallbackTask;
8
use AsyncPHP\Icicle\Database\Connector;
9
use AsyncPHP\Remit\Client;
10
use AsyncPHP\Remit\Client\ZeroMqClient;
11
use AsyncPHP\Remit\Location\InMemoryLocation;
12
use AsyncPHP\Remit\Server;
13
use AsyncPHP\Remit\Server\ZeroMqServer;
14
use Aura\Sql\ExtendedPdo;
15
use Icicle\Loop;
16
use Icicle\Promise\Deferred;
17
use Icicle\Promise\PromiseInterface;
18
use InvalidArgumentException;
19
use PDO;
20
21
final class DoormanConnector implements Connector
22
{
23
    /**
24
     * @var int
25
     */
26
    private $id = 1;
27
28
    /**
29
     * @var array
30
     */
31
    private $deferred = [];
32
33
    /**
34
     * @var Manager
35
     */
36
    private $manager;
37
38
    /**
39
     * @var Server
40
     */
41
    private $server;
42
43
    /**
44
     * @var Client[]
45
     */
46
    private $clients = [];
47
48
    /**
49
     * @var int
50
     */
51
    private $client = 0;
52
53
    /**
54
     * @inheritdoc
55
     *
56
     * @param array $config
57
     *
58
     * @return PromiseInterface
59
     *
60
     * @throws InvalidArgumentException
61
     */
62 1
    public function connect(array $config)
63
    {
64 1
        $this->manager = new ProcessManager();
65
66 1
        $this->validate($config);
67
        $this->connectRemit($config);
68
        $this->connectDoorman($config);
69
70
        $this->server->addListener("result", function ($result, $id) {
71
            if (isset($this->deferred[$id])) {
72
                $this->deferred[$id]->resolve($result);
73
                unset($this->deferred[$id]);
74
            }
75
        });
76
77
        $this->server->addListener("error", function ($error, $id) {
78
            if (isset($this->deferred[$id])) {
79
                $this->deferred[$id]->reject($error);
80
                unset($this->deferred[$id]);
81
            }
82
        });
83
84
        Loop\periodic(0, function () {
85
            $this->manager->tick();
86
            $this->server->tick();
87
        });
88
    }
89
90
    /**
91
     * @param array $config
92
     *
93
     * @throws InvalidArgumentException
94
     */
95 1
    private function validate(array $config)
96
    {
97 1
        if (!isset($config["remit"])) {
98 1
            throw new InvalidArgumentException("Undefined remit");
99
        }
100
101
        if (!isset($config["remit"]["driver"])) {
102
            throw new InvalidArgumentException("Undefined remit driver");
103
        }
104
105
        if (!isset($config["remit"]["server"])) {
106
            throw new InvalidArgumentException("Undefined remit server");
107
        }
108
109
        if (!isset($config["remit"]["clients"])) {
110
            throw new InvalidArgumentException("Undefined remit clients");
111
        }
112
113
        if ($config["remit"]["driver"] === "zeromq") {
114
            if (!isset($config["remit"]["server"]["port"])) {
115
                throw new InvalidArgumentException("Undefined remit server port");
116
            }
117
118
            foreach ($config["remit"]["clients"] as $i => $client) {
119
                if (!isset($client["port"])) {
120
                    throw new InvalidArgumentException("Undefined remit client ({$i}) port");
121
                }
122
            }
123
        } else {
124
            throw new InvalidArgumentException("Unrecognised remit driver");
125
        }
126
    }
127
128
    /**
129
     * @param array $config
130
     */
131
    private function connectRemit(array $config)
132
    {
133
        $server = $config["remit"]["server"];
134
135
        if ($config["remit"]["driver"] === "zeromq") {
136
            $server = array_merge([
137
                "host" => "127.0.0.1",
138
            ], $server);
139
140
            $this->server = new ZeroMqServer(
141
                new InMemoryLocation(
142
                    $server["host"],
143
                    $server["port"]
144
                )
145
            );
146
147
            foreach ($config["remit"]["clients"] as $i => $client) {
148
                $client = array_merge([
149
                    "host" => "127.0.0.1",
150
                ], $client);
151
152
                $this->clients[] = new ZeroMqClient(
153
                    new InMemoryLocation(
154
                        $client["host"],
155
                        $client["port"]
156
                    )
157
                );
158
            }
159
        }
160
    }
161
162
    /**
163
     * @param array $config
164
     */
165
    private function connectDoorman(array $config)
166
    {
167
        $server = $config["remit"]["server"];
168
169
        if ($config["remit"]["driver"] === "zeromq") {
170
            foreach ($config["remit"]["clients"] as $i => $client) {
171
                $task = new ProcessCallbackTask(function () use ($config, $server, $client) {
172
                    $config = array_merge([
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $config, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
173
                        "host" => "127.0.0.1",
174
                        "port" => 3306,
175
                    ], $config);
176
177
                    $server = array_merge([
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $server, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
178
                        "host" => "127.0.0.1",
179
                    ], $server);
180
181
                    $client = array_merge([
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $client, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
182
                        "host" => "127.0.0.1",
183
                    ], $client);
184
185
                    $remitServer = new ZeroMqServer(
186
                        new InMemoryLocation(
187
                            $client["host"],
188
                            $client["port"]
189
                        )
190
                    );
191
192
                    $remitClient = new ZeroMqClient(
193
                        new InMemoryLocation(
194
                            $server["host"],
195
                            $server["port"]
196
                        )
197
                    );
198
199
                    $database = $config["database"];
200
                    $host = $config["host"];
201
                    $port = $config["port"];
202
                    $username = $config["username"];
203
                    $password = $config["password"];
204
205
                    $connection = new ExtendedPdo(
206
                        new PDO(
207
                            "mysql:dbname={$database};host={$host};port={$port}",
208
                            $username, $password
209
                        )
210
                    );
211
212
                    $remitServer->addListener("query", function ($query, $values, $id) use ($remitClient, $connection) {
213
                        $remitClient->emit("result", [$connection->fetchAll($query, $values), $id]);
214
                    });
215
216
                    Loop\periodic(0, function () use ($remitServer) {
217
                        $remitServer->tick();
218
                    });
219
220
                    Loop\run();
221
                });
222
223
                $this->manager->addTask($task);
224
            }
225
        }
226
    }
227
228
    /**
229
     * @inheritdoc
230
     *
231
     * @param string $query
232
     * @param array $values
233
     *
234
     * @return PromiseInterface
235
     *
236
     * @throws InvalidArgumentException
237
     */
238
    public function query($query, $values)
239
    {
240
        $id = $this->id++;
241
        $client = $this->client++;
242
243
        if ($this->client >= count($this->clients)) {
244
            $this->client = 0;
245
        }
246
247
        $deferred = new Deferred();
248
249
        $this->clients[$client]->emit("query", [$query, $values, "d{$id}"]);
250
251
        $this->deferred["d{$id}"] = $deferred;
252
253
        return $deferred->getPromise();
254
    }
255
}
256