6
6
use Interop \Amqp \AmqpMessage as InteropAmqpMessage ;
7
7
use Interop \Amqp \AmqpQueue ;
8
8
use Interop \Amqp \Impl \AmqpMessage ;
9
- use Interop \Queue \Exception ;
10
9
use Interop \Queue \InvalidMessageException ;
11
10
use Interop \Queue \PsrMessage ;
12
11
@@ -32,11 +31,6 @@ class AmqpConsumer implements InteropAmqpConsumer
32
31
*/
33
32
private $ extQueue ;
34
33
35
- /**
36
- * @var bool
37
- */
38
- private $ isInit ;
39
-
40
34
/**
41
35
* @var string
42
36
*/
@@ -65,19 +59,13 @@ public function __construct(AmqpContext $context, AmqpQueue $queue, Buffer $buff
65
59
$ this ->buffer = $ buffer ;
66
60
$ this ->receiveMethod = $ receiveMethod ;
67
61
$ this ->flags = self ::FLAG_NOPARAM ;
68
-
69
- $ this ->isInit = false ;
70
62
}
71
63
72
64
/**
73
65
* {@inheritdoc}
74
66
*/
75
67
public function setConsumerTag ($ consumerTag )
76
68
{
77
- if ($ this ->isInit ) {
78
- throw new Exception ('Consumer tag is not mutable after it has been subscribed to broker ' );
79
- }
80
-
81
69
$ this ->consumerTag = $ consumerTag ;
82
70
}
83
71
@@ -157,7 +145,7 @@ public function receive($timeout = 0)
157
145
public function receiveNoWait ()
158
146
{
159
147
if ($ extMessage = $ this ->getExtQueue ()->get (Flags::convertConsumerFlags ($ this ->flags ))) {
160
- return $ this ->convertMessage ($ extMessage );
148
+ return $ this ->context -> convertMessage ($ extMessage );
161
149
}
162
150
}
163
151
@@ -213,85 +201,44 @@ private function receiveBasicGet($timeout)
213
201
*/
214
202
private function receiveBasicConsume ($ timeout )
215
203
{
216
- if ($ this ->isInit && $ message = $ this ->buffer ->pop ($ this ->getExtQueue ()->getConsumerTag ())) {
217
- return $ message ;
204
+ if (false == $ this ->consumerTag ) {
205
+ $ this ->context ->subscribe ($ this , function (InteropAmqpMessage $ message ) {
206
+ $ this ->buffer ->push ($ message ->getConsumerTag (), $ message );
207
+
208
+ return false ;
209
+ });
218
210
}
219
211
220
- /** @var \AMQPQueue $extQueue */
221
- $ extConnection = $ this ->getExtQueue ()->getChannel ()->getConnection ();
212
+ if ($ message = $ this ->buffer ->pop ($ this ->consumerTag )) {
213
+ return $ message ;
214
+ }
222
215
223
- $ originalTimeout = $ extConnection ->getReadTimeout ();
224
- try {
225
- $ extConnection ->setReadTimeout ($ timeout / 1000 );
216
+ while (true ) {
217
+ $ start = microtime (true );
226
218
227
- if (false == $ this ->isInit ) {
228
- $ this ->getExtQueue ()->consume (null , Flags::convertConsumerFlags ($ this ->flags ), $ this ->consumerTag );
219
+ $ this ->context ->consume ($ timeout );
229
220
230
- $ this ->isInit = true ;
221
+ if ($ message = $ this ->buffer ->pop ($ this ->consumerTag )) {
222
+ return $ message ;
231
223
}
232
224
233
- /** @var AmqpMessage|null $message */
234
- $ message = null ;
235
-
236
- $ this ->getExtQueue ()->consume (function (\AMQPEnvelope $ extEnvelope , \AMQPQueue $ q ) use (&$ message ) {
237
- $ message = $ this ->convertMessage ($ extEnvelope );
238
- $ message ->setConsumerTag ($ q ->getConsumerTag ());
239
-
240
- if ($ this ->getExtQueue ()->getConsumerTag () == $ q ->getConsumerTag ()) {
241
- return false ;
242
- }
225
+ // is here when consumed message is not for this consumer
243
226
244
- // not our message, put it to buffer and continue.
245
- $ this -> buffer -> push ( $ q -> getConsumerTag (), $ message );
246
-
247
- $ message = null ;
227
+ // as timeout is infinite have to continue consumption, but it can overflow message buffer
228
+ if ( $ timeout <= 0 ) {
229
+ continue ;
230
+ }
248
231
249
- return true ;
250
- }, AMQP_JUST_CONSUME );
232
+ // compute remaining timeout and continue until time is up
233
+ $ stop = microtime (true );
234
+ $ timeout -= ($ stop - $ start ) * 1000 ;
251
235
252
- return $ message ;
253
- } catch (\AMQPQueueException $ e ) {
254
- if ('Consumer timeout exceed ' == $ e ->getMessage ()) {
255
- return null ;
236
+ if ($ timeout <= 0 ) {
237
+ break ;
256
238
}
257
-
258
- throw $ e ;
259
- } finally {
260
- $ extConnection ->setReadTimeout ($ originalTimeout );
261
239
}
262
240
}
263
241
264
- /**
265
- * @param \AMQPEnvelope $extEnvelope
266
- *
267
- * @return AmqpMessage
268
- */
269
- private function convertMessage (\AMQPEnvelope $ extEnvelope )
270
- {
271
- $ message = new AmqpMessage (
272
- $ extEnvelope ->getBody (),
273
- $ extEnvelope ->getHeaders (),
274
- [
275
- 'message_id ' => $ extEnvelope ->getMessageId (),
276
- 'correlation_id ' => $ extEnvelope ->getCorrelationId (),
277
- 'app_id ' => $ extEnvelope ->getAppId (),
278
- 'type ' => $ extEnvelope ->getType (),
279
- 'content_encoding ' => $ extEnvelope ->getContentEncoding (),
280
- 'content_type ' => $ extEnvelope ->getContentType (),
281
- 'expiration ' => $ extEnvelope ->getExpiration (),
282
- 'priority ' => $ extEnvelope ->getPriority (),
283
- 'reply_to ' => $ extEnvelope ->getReplyTo (),
284
- 'timestamp ' => $ extEnvelope ->getTimeStamp (),
285
- 'user_id ' => $ extEnvelope ->getUserId (),
286
- ]
287
- );
288
- $ message ->setRedelivered ($ extEnvelope ->isRedelivery ());
289
- $ message ->setDeliveryTag ($ extEnvelope ->getDeliveryTag ());
290
- $ message ->setRoutingKey ($ extEnvelope ->getRoutingKey ());
291
-
292
- return $ message ;
293
- }
294
-
295
242
/**
296
243
* @return \AMQPQueue
297
244
*/
0 commit comments