Completed
Push — GearmanClient ( 413f25 )
by Vasily
04:10
created

Connection::doHigh()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 8
Ratio 100 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 8
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 4
1
<?php
2
namespace PHPDaemon\Clients\GearmanClient;
3
4
use PHPDaemon\Network\ClientConnection;
5
6
7
/**
8
 * @package NetworkClients
9
 * @subpackage GearmanClient
10
 * @protocol http://gearman.org/protocol/
11
 *
12
 * @interface http://php.net/manual/ru/class.gearmanclient.php
13
 *
14
 * @author Popov Gennadiy <[email protected]>
15
 */
16
class  Connection extends ClientConnection {
0 ignored issues
show
Coding Style introduced by
Expected 1 space between class keyword and class name; 2 found
Loading history...
17
18
    /**
19
     * Request codes
20
     *
21
     * @var array
22
     */
23
    private $requestCommandList = [
24
        'CAN_DO' => 1,
25
        'CANT_DO' => 2,
26
        'RESET_ABILITIES' => 3,
27
        'PRE_SLEEP' => 4,
28
        'SUBMIT_JOB' => 7,
29
        'GRAB_JOB' => 9,
30
        'WORK_STATUS' => 12,
31
        'WORK_COMPLETE' => 13,
32
        'WORK_FAIL' => 14,
33
        'GET_STATUS' => 15,
34
        'ECHO_REQ' => 16,
35
        'SUBMIT_JOB_BG' => 18,
36
        'SUBMIT_JOB_HIGH' => 21,
37
        'SET_CLIENT_ID' => 22,
38
        'CAN_DO_TIMEOUT' => 23,
39
        'ALL_YOURS' => 24,
40
        'WORK_EXCEPTION' => 25,
41
        'OPTION_REQ' => 26,
42
        'OPTION_RES' => 27,
43
        'WORK_DATA' => 28,
44
        'WORK_WARNING' => 29,
45
        'GRAB_JOB_UNIQ' => 30,
46
        'SUBMIT_JOB_HIGH_BG' => 32,
47
        'SUBMIT_JOB_LOW' => 33,
48
        'SUBMIT_JOB_LOW_BG' => 34,
49
        'SUBMIT_JOB_SCHED' => 35,
50
        'SUBMIT_JOB_EPOCH' => 36,
51
    ];
52
53
    /**
54
     * Response codes
55
     *
56
     * @var array
57
     */
58
    private $responseCommandList = [
59
        'NOOP' => 6,
60
        'JOB_CREATED' => 8,
61
        'NO_JOB' => 10,
62
        'JOB_ASSIGN' => 11,
63
        'WORK_STATUS' => 12,
64
        'WORK_COMPLETE' => 13,
65
        'WORK_FAIL' => 14,
66
        'ECHO_RES' => 17,
67
        'ERROR' => 19,
68
        'STATUS_RES' => 20,
69
        'WORK_EXCEPTION' => 25,
70
        'OPTION_RES' => 27,
71
        'WORK_WARNING' => 29,
72
        'JOB_ASSIGN_UNIQ' => 31,
73
    ];
74
75
    /**
76
     * Magic code for request
77
     */
78
    const MAGIC_REQUEST         = "\0REQ";
79
80
    /**
81
     * Magic code for response
82
     */
83
    const MAGIC_RESPONSE        = "\0RES";
84
85
    /*
86
     * Byte length of header
87
     */
88
    const HEADER_LENGTH         = 12;
89
90
    /**
91
     * Header binary format
92
     */
93
    const HEADER_WRITE_FORMAT   = "a4NN";
94
95
    /**
96
     * Header read format
97
     */
98
    const HEADER_READ_FORMAT    = "a4magic/Ntype/Nsize";
99
100
    /**
101
     * Delimeter for function arguments
102
     */
103
    const ARGS_DELIMITER        = "\0";
104
105
    /**
106
     * Flag
107
     * @var bool
108
     */
109
    private $jobAwaitResult     = false;
110
111
    /**
112
     * Generate a random string token
113
     *
114
     * @param int $length How many characters do we want?
115
     * @param string $keySpaces A string of all possible characters  to select from
116
     *
117
     * @return string
118
     */
119
    private function generateUniqueToken($length = 10, $keySpaces = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 135 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
120
121
        $half = intval($length / 2);
122
        $result = substr(str_shuffle($keySpaces), 0, $half) . substr(str_shuffle($keySpaces), 0, $length - $half);
123
124
        return $result;
125
    }
126
127
    /**
128
     * Called when new data received
129
     *
130
     * @return void
131
     */
132
    public function onRead() {
133
134
        if (($head = $this->readExact(static::HEADER_LENGTH)) === false) {
135
            return;
136
        }
137
138
        $head = unpack(static::HEADER_READ_FORMAT, $head);
139
        list($magic, $type, $size) = array_values($head);
140
141
        $type_array = $magic === static::MAGIC_RESPONSE ? $this->responseCommandList : $this->requestCommandList;
142
143
        $TYPE_CODE = NULL;
144
145
        foreach ($type_array as $key => $info) {
146
147
            if (intval($info[0]) === intval($type)) {
148
                $TYPE_CODE = $key;
149
                break;
150
            }
151
        }
152
153
        if (!$this->jobAwaitResult || 'WORK_COMPLETE' === $TYPE_CODE) {
154
155
            $body = $this->read($size);
156
            $argv = strlen($body) ? explode(static::ARGS_DELIMITER, $body) : [];
157
158
            $this->jobAwaitResult = false;
159
            $this->onResponse->executeOne($this, $argv);
160
161
            $this->checkFree();
162
            return ;
163
        }
164
    }
165
166
    /**
167
     * Function send ECHO
168
     *
169
     * @param $payload
170
     * @param callable|null $cb
171
     */
172
    public function sendEcho ($payload, callable $cb = null) {
173
        $this->sendCommand('ECHO_REQ', $payload, $cb);
174
    }
175
176
    /**
177
     * Function run task and wait result in callback
178
     *
179
     * @param $function_name
180
     * @param $payload
181
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
182
     * @param null $unique
183
     */
184 View Code Duplication
    public function runJob($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
186
        if ($unique) {
187
            $unique =  $this->generateUniqueToken();
188
        }
189
190
        $this->jobAwaitResult = true;
191
        $this->sendCommand('SUBMIT_JOB', [$function_name, $unique,  $payload], $resultCallback);
192
    }
193
194
    /**
195
     * Function run task and wait result in callback
196
     *
197
     * @param $function_name
198
     * @param $payload
199
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
200
     * @param null $unique
201
     */
202 View Code Duplication
    public function doNormal($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
203
204
        if ($unique) {
205
            $unique = $this->generateUniqueToken();
206
        }
207
208
        $this->sendCommand('SUBMIT_JOB', [$function_name, $unique,  $payload], $resultCallback);
209
    }
210
211
    /**
212
     * Function run task in background
213
     *
214
     * @param $function_name
215
     * @param $payload
216
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
217
     * @param null $unique
218
     */
219 View Code Duplication
    public function doBackground($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
220
221
        if ($unique) {
222
            $unique = $this->generateUniqueToken();
223
        }
224
225
        $this->sendCommand('SUBMIT_JOB_BG', [$function_name, $unique,  $payload], $resultCallback);
226
    }
227
228
    /**
229
     * Function run task with high prority
230
     *
231
     * @param $function_name
232
     * @param $payload
233
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
234
     * @param stirng $unique
0 ignored issues
show
Documentation introduced by
Should the type for parameter $unique not be stirng|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
235
     */
236 View Code Duplication
    public function doHigh($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
238
        if (!is_string($unique)) {
239
            $unique = $this->generateUniqueToken();
240
        }
241
242
        $this->sendCommand('SUBMIT_JOB_HIGH', [$function_name, $unique,  $payload], $resultCallback);
243
    }
244
245
    /**
246
     * Function run task in background with high prority
247
     *
248
     * @param $function_name
249
     * @param $payload
250
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
251
     * @param null $unique
252
     */
253 View Code Duplication
    public function doHighBackground($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
254
255
        if ($unique) {
256
            $unique = $this->generateUniqueToken();
257
        }
258
259
        $this->sendCommand('SUBMIT_JOB_HIGH_BG', [$function_name, $unique,  $payload], $resultCallback);
260
    }
261
262
    /**
263
     * Function run task with low priority
264
     *
265
     * @param $function_name
266
     * @param $payload
267
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
268
     * @param null $unique
269
     */
270 View Code Duplication
    public function doLow($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
272
        if ($unique) {
273
            $unique = $this->generateUniqueToken();
274
        }
275
276
        $this->sendCommand('SUBMIT_JOB_LOW', [$function_name, $unique,  $payload], $resultCallback);
277
    }
278
279
    /**
280
     * Function run task in background with low priority
281
     *
282
     * @param $function_name
283
     * @param $payload
284
     * @param null $context
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
285
     * @param null $unique
286
     */
287 View Code Duplication
    public function doLowBackground($function_name, $payload, callable $resultCallback, $unique = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
288
289
        if ($unique) {
290
            $unique = $this->generateUniqueToken();
291
        }
292
293
        $this->sendCommand('SUBMIT_JOB_LOW_BG', [$function_name, $unique,  $payload], $resultCallback);
294
    }
295
296
    /**
297
     * Get job status
298
     * 
299
     * @param $job_handle Job handle that was given in JOB_CREATED packet.
300
     *
301
     */
302
    public function doStatus($job_handle, callable $resultCallback) {
303
        $this->sendCommand('GET_STATUS', [$job_handle], $resultCallback);
304
    }
305
306
    /**
307
     * Function set settings for current connection
308
     * Available settings
309
     * 'exceptions' - Forward WORK_EXCEPTION packets to the client.
310
     *
311
     * @url http://gearman.org/protocol/
312
     *
313
     *
314
     * @param int $option_name
315
     * @param callable $doneCallback
316
     */
317
    public function setConnectionOption($option_name, callable $doneCallback) {
318
        $this->sendCommand('OPTION_RES', [$option_name], $doneCallback);
319
    }
320
321
    /**
322
     * Low level commands sender
323
     *
324
     * @param $commandName
325
     * @param $payload
326
     * @param $doneCallback callable|null $doneCallback
327
     */
328
    private function sendCommand($commandName, $payload, callable $doneCallback = null) {
329
330
        $payload = (array) $payload;
331
        $payload = array_map(function($item){ return !is_scalar($item) ? serialize($item) : $item; }, $payload);
332
        $payload = implode(static::ARGS_DELIMITER, $payload);
333
334
        $len = strlen($payload);
335
336
        list($command_id) = $this->requestCommandList[$commandName];
337
        $this->onResponse->push($doneCallback);
0 ignored issues
show
Bug introduced by
It seems like $doneCallback defined by parameter $doneCallback on line 328 can also be of type null; however, PHPDaemon\Structures\StackCallbacks::push() does only seem to accept callable, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
338
339
        $sendData = pack(static::HEADER_WRITE_FORMAT, static::MAGIC_REQUEST, $command_id, $len);
340
        $sendData .= $payload;
341
342
        $this->write($sendData);
343
    }
344
}