1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Phive Queue package. |
5
|
|
|
* |
6
|
|
|
* (c) Eugene Leonovich <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Phive\Queue; |
13
|
|
|
|
14
|
|
|
class SysVQueue implements Queue |
15
|
|
|
{ |
16
|
|
|
/** |
17
|
|
|
* @var int |
18
|
|
|
*/ |
19
|
|
|
private $key; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @var bool |
23
|
|
|
*/ |
24
|
|
|
private $serialize; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var int |
28
|
|
|
*/ |
29
|
|
|
private $perms = 0666; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var int |
33
|
|
|
*/ |
34
|
|
|
private $itemMaxLength = 8192; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var resource |
38
|
|
|
*/ |
39
|
|
|
private $queue; |
40
|
|
|
|
41
|
33 |
|
public function __construct($key, $serialize = null, $perms = null) |
42
|
|
|
{ |
43
|
33 |
|
$this->key = $key; |
44
|
33 |
|
$this->serialize = (bool) $serialize; |
45
|
|
|
|
46
|
33 |
|
if (null !== $perms) { |
47
|
1 |
|
$this->perms = $perms; |
48
|
1 |
|
} |
49
|
33 |
|
} |
50
|
|
|
|
51
|
1 |
|
public function setItemMaxLength($length) |
52
|
|
|
{ |
53
|
1 |
|
$this->itemMaxLength = $length; |
54
|
1 |
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* {@inheritdoc} |
58
|
|
|
*/ |
59
|
25 |
|
public function push($item, $eta = null) |
60
|
|
|
{ |
61
|
25 |
|
$eta = QueueUtils::normalizeEta($eta); |
62
|
|
|
|
63
|
25 |
|
if (!msg_send($this->getQueue(), $eta, $item, $this->serialize, false, $errorCode)) { |
64
|
4 |
|
throw new QueueException($this, self::getErrorMessage($errorCode), $errorCode); |
65
|
|
|
} |
66
|
20 |
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* {@inheritdoc} |
70
|
|
|
*/ |
71
|
21 |
|
public function pop() |
72
|
|
|
{ |
73
|
21 |
|
if (!msg_receive($this->getQueue(), -time(), $eta, $this->itemMaxLength, $item, $this->serialize, MSG_IPC_NOWAIT, $errorCode)) { |
74
|
4 |
|
throw (MSG_ENOMSG === $errorCode) |
75
|
4 |
|
? new NoItemAvailableException($this) |
76
|
4 |
|
: new QueueException($this, self::getErrorMessage($errorCode), $errorCode); |
77
|
|
|
} |
78
|
|
|
|
79
|
18 |
|
return $item; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* {@inheritdoc} |
84
|
|
|
*/ |
85
|
7 |
|
public function count() |
86
|
|
|
{ |
87
|
7 |
|
$data = msg_stat_queue($this->getQueue()); |
88
|
|
|
|
89
|
6 |
|
if (!is_array($data)) { |
90
|
1 |
|
throw new QueueException($this, 'Failed to get the meta data for the queue.'); |
91
|
|
|
} |
92
|
|
|
|
93
|
6 |
|
return $data['msg_qnum']; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* {@inheritdoc} |
98
|
|
|
*/ |
99
|
3 |
|
public function clear() |
100
|
|
|
{ |
101
|
3 |
|
if (!msg_remove_queue($this->getQueue())) { |
102
|
1 |
|
throw new QueueException($this, 'Failed to destroy the queue.'); |
103
|
|
|
} |
104
|
|
|
|
105
|
1 |
|
$this->queue = null; |
106
|
1 |
|
} |
107
|
|
|
|
108
|
32 |
|
private function getQueue() |
109
|
|
|
{ |
110
|
32 |
|
if (!is_resource($this->queue)) { |
111
|
32 |
|
$this->queue = msg_get_queue($this->key, $this->perms); |
112
|
|
|
|
113
|
32 |
|
if (!is_resource($this->queue)) { |
114
|
4 |
|
throw new QueueException($this, 'Failed to create/attach to the queue.'); |
115
|
|
|
} |
116
|
28 |
|
} |
117
|
|
|
|
118
|
28 |
|
return $this->queue; |
119
|
|
|
} |
120
|
|
|
|
121
|
6 |
|
private static function getErrorMessage($errorCode) |
122
|
|
|
{ |
123
|
6 |
|
if ($errorCode) { |
124
|
3 |
|
return posix_strerror($errorCode).'.'; |
125
|
|
|
} |
126
|
|
|
|
127
|
3 |
|
$error = error_get_last(); |
128
|
3 |
|
if ($error && 0 === strpos($error['message'], 'msg_')) { |
|
|
|
|
129
|
3 |
|
return preg_replace('/^msg_[^:]+?\:\s/', '', $error['message']); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
return 'Unknown error.'; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.