99use Illuminate \Queue \InvalidPayloadException ;
1010use Illuminate \Queue \Queue ;
1111use PhpAmqpLib \Channel \AMQPChannel ;
12- use PhpAmqpLib \Connection \AMQPConnection ;
1312use PhpAmqpLib \Connection \AMQPStreamConnection ;
1413use PhpAmqpLib \Message \AMQPMessage ;
1514use PhpAmqpLib \Wire \AMQPTable ;
@@ -30,7 +29,7 @@ class AMQPQueue extends Queue implements QueueContract
3029 const EXCHANGE_TYPE_FANOUT = 'fanout ' ;
3130
3231 /**
33- * @var AMQPConnection Connection to amqp compatible server
32+ * @var AMQPStreamConnection Connection to amqp compatible server
3433 */
3534 protected $ connection ;
3635
@@ -69,6 +68,11 @@ class AMQPQueue extends Queue implements QueueContract
6968 */
7069 private $ declareQueues ;
7170
71+ /**
72+ * @var int
73+ */
74+ private $ retryAfter ;
75+
7276 /**
7377 * @param AMQPStreamConnection $connection
7478 * @param string $defaultQueueName Default queue name
@@ -83,6 +87,7 @@ class AMQPQueue extends Queue implements QueueContract
8387 * @param string $exchangeName Exchange name
8488 * @param mixed $exchangeType Exchange type
8589 * @param mixed $exchangeFlags Exchange flags
90+ * @param mixed $retryAfter Optional timeout for failed jobs
8691 */
8792 public function __construct (
8893 AMQPStreamConnection $ connection ,
@@ -93,7 +98,8 @@ public function __construct(
9398 $ defaultChannelId = null ,
9499 $ exchangeName = '' ,
95100 $ exchangeType = null ,
96- $ exchangeFlags = []
101+ $ exchangeFlags = [],
102+ $ retryAfter = 0
97103 ) {
98104 $ this ->connection = $ connection ;
99105 $ this ->defaultQueueName = $ defaultQueueName ?: 'default ' ;
@@ -103,6 +109,7 @@ public function __construct(
103109 $ this ->defaultChannelId = $ defaultChannelId ;
104110 $ this ->exchangeName = $ exchangeName ;
105111 $ this ->channel = $ connection ->channel ($ this ->defaultChannelId );
112+ $ this ->retryAfter = $ retryAfter ;
106113
107114 if ($ exchangeName !== null ) {
108115 $ this ->declareExchange ($ exchangeName , $ exchangeType , $ exchangeFlags );
@@ -135,22 +142,29 @@ protected function declareExchange($exchangeName, $exchangeType, array $exchange
135142 call_user_func_array ([$ this ->channel , 'exchange_declare ' ], $ flags );
136143 }
137144
145+ /**
146+ * @return array
147+ */
148+ public function getCustomMessageOptions (){
149+ return ['retryAfter ' => $ this ->retryAfter ];
150+ }
151+
138152 /**
139153 * Push a new job onto the queue.
140154 *
141155 * @param string $job Job implementation class name
142156 * @param mixed $data Job custom data. Usually array
143157 * @param string $queue Queue name, if different from the default one
144158 *
145- * @throws InvalidPayloadException
159+ * @throws \Illuminate\Queue\ InvalidPayloadException
146160 * @throws AMQPException
147161 * @return bool Always true
148162 */
149163 public function push ($ job , $ data = '' , $ queue = null )
150164 {
151165 $ queue = $ this ->prepareQueue ($ queue );
152- $ amqpMessage = $ this ->prepareMessage ($ job , $ data );
153- $ this ->channel ->basic_publish ($ amqpMessage , $ this ->exchangeName , $ this ->getRoutingKey ($ queue ));
166+ $ payload = new AMQPMessage ( $ this ->createPayload ($ job , $ queue , $ data), $ this -> messageProperties );
167+ $ this ->channel ->basic_publish ($ payload , $ this ->exchangeName , $ this ->getRoutingKey ($ queue ));
154168
155169 return true ;
156170 }
@@ -163,14 +177,14 @@ public function push($job, $data = '', $queue = null)
163177 * @param string $queue Queue name, if different from the default one
164178 *
165179 * @return bool
166- * @throws InvalidPayloadException
180+ * @throws \Illuminate\Queue\ InvalidPayloadException
167181 * @throws AMQPException
168182 */
169183 public function addMessageToBatch ($ job , $ data = '' , $ queue = null )
170184 {
171185 $ queue = $ this ->prepareQueue ($ queue );
172- $ amqpMessage = $ this ->prepareMessage ($ job , $ data );
173- $ this ->channel ->batch_basic_publish ($ amqpMessage , $ this ->exchangeName , $ this ->getRoutingKey ($ queue ));
186+ $ payload = new AMQPMessage ( $ this ->createPayload ($ job , $ queue , $ data), $ this -> messageProperties );
187+ $ this ->channel ->batch_basic_publish ($ payload , $ this ->exchangeName , $ this ->getRoutingKey ($ queue ));
174188
175189 return true ;
176190 }
@@ -270,9 +284,6 @@ protected function getRoutingKey($queue)
270284 */
271285 public function pushRaw ($ payload , $ queue = null , array $ options = [])
272286 {
273- // NB: DYNAMIC PRIORITY IS NOT IMPLEMENTED FOR RAW MESSAGES,
274- // NB: NEED TO SET THE $this->messageProperties['priority'] FIELD
275-
276287 $ queue = $ this ->prepareQueue ($ queue );
277288 $ amqpPayload = new AMQPMessage ($ payload , $ this ->messageProperties );
278289 $ this ->channel ->basic_publish ($ amqpPayload , $ this ->exchangeName , $ queue );
@@ -288,7 +299,7 @@ public function pushRaw($payload, $queue = null, array $options = [])
288299 * @param string $queue Queue name, if different from the default one
289300 *
290301 * @return bool Always true
291- * @throws InvalidPayloadException
302+ * @throws \Illuminate\Queue\ InvalidPayloadException
292303 * @throws AMQPException
293304 */
294305 public function later ($ delay , $ job , $ data = '' , $ queue = null )
@@ -300,8 +311,8 @@ public function later($delay, $job, $data = '', $queue = null)
300311 $ queue = $ this ->prepareQueue ($ queue );
301312 $ delayedQueueName = $ this ->declareDelayedQueue ($ queue , $ delay );
302313
303- $ amqpMessage = $ this ->prepareMessage ($ job , $ data );
304- $ this ->channel ->basic_publish ($ amqpMessage , $ this ->exchangeName , $ delayedQueueName );
314+ $ payload = new AMQPMessage ( $ this ->createPayload ($ job , $ queue , $ data), $ this -> messageProperties );
315+ $ this ->channel ->basic_publish ($ payload , $ this ->exchangeName , $ delayedQueueName );
305316 return true ;
306317 }
307318
@@ -334,7 +345,7 @@ public function declareDelayedQueue($destinationQueueName, $delay)
334345 'arguments ' => new AMQPTable ([
335346 'x-dead-letter-exchange ' => '' ,
336347 'x-dead-letter-routing-key ' => $ destinationQueueName ,
337- 'x-message-ttl ' => $ delay * 1000 ,
348+ 'x-message-ttl ' => intval ( $ delay * 1000 ) ,
338349 ]),
339350 ]);
340351
@@ -414,73 +425,55 @@ private function prepareQueue($queue)
414425 return $ queue ;
415426 }
416427
417-
418-
419- // FNX - ADD DYNAMIC PRIORITY TO MESSAGE
420-
421428 /**
422- * @param string $job
423- * @param mixed $data
429+ * Create a payload string from the given job and data.
430+ *
431+ * @param string $job
432+ * @param string $queue
433+ * @param mixed $data
434+ * @return string
424435 *
425- * @return AMQPMessage
426- * @throws InvalidPayloadException
436+ * @throws \Illuminate\Queue\InvalidPayloadException
427437 */
428- protected function prepareMessage ($ job , $ data )
438+ protected function createPayload ($ job , $ queue , $ data = '' )
429439 {
430- $ payloadJson = $ this ->createPayload ($ job , $ data );
431- $ arrPayload = json_decode ($ payloadJson , true );
432-
433- // OVERRIDE PRIORITY
434- // NB: IMPLEMENT QUEUE DEFAULT PRIORITY USING THE FIELD `message_properties['priority']` IN THE CONFIG
435- $ props = $ this ->messageProperties ;
436- if (!empty ($ arrPayload ['priority ' ]) && $ arrPayload ['priority ' ] > 0 )
437- $ props ['priority ' ] = $ arrPayload ['priority ' ];
438-
439- return new AMQPMessage ($ payloadJson , $ props );
440+ $ data = is_array ($ data ) ? array_merge ($ data , $ this ->getCustomMessageOptions ()) : $ this ->getCustomMessageOptions ();
441+ $ payload = json_encode ($ this ->createPayloadArray ($ job , $ queue , $ data ));
442+ if (JSON_ERROR_NONE !== json_last_error ()) {
443+ throw new InvalidPayloadException (
444+ 'Unable to JSON encode payload. Error code: ' .json_last_error ()
445+ );
446+ }
440447
448+ return $ payload ;
441449 }
442450
443- // FNX - OVERRIDE PAYLOAD GENERATION
444451 /**
445452 * Create a payload for an object-based queue handler.
446453 *
447454 * @param mixed $job
455+ * @param string $queue
448456 * @return array
449457 */
450- protected function createObjectPayload ($ job )
458+ protected function createObjectPayload ($ job, $ queue )
451459 {
452- return [
453- 'data ' => [
454- 'command ' => serialize (clone $ job ),
455- 'commandName ' => get_class ($ job ),
456- ],
460+ $ payload = $ this ->withCreatePayloadHooks ($ queue , [
457461 'displayName ' => $ this ->getDisplayName ($ job ),
458462 'job ' => 'Illuminate\Queue\CallQueuedHandler@call ' ,
459- 'maxTries ' => empty ( $ job ->tries ) ? null : $ job -> tries ,
460- 'timeout ' => empty ( $ job ->timeout ) ? null : $ job -> timeout ,
463+ 'maxTries ' => $ job ->tries ?? null ,
464+ 'timeout ' => $ job ->timeout ?? null ,
461465 'timeoutAt ' => $ this ->getJobExpiration ($ job ),
462- 'priority ' => empty ($ job ->priority ) ? null : $ job ->priority ,
463- ];
464- }
465- /**
466- * Create a typical, string based queue payload array.
467- *
468- * @param string $job
469- * @param mixed $payload
470- *
471- * @return array
472- */
473- protected function createStringPayload ($ job , $ payload )
474- {
475- return [
476- 'displayName ' => is_string ($ job ) ? explode ('@ ' , $ job )[0 ] : null ,
477- 'job ' => $ job ,
478- 'maxTries ' => $ payload ['maxTries ' ],
479- 'timeout ' => $ payload ['timeout ' ],
480- 'data ' => $ payload ['data ' ],
481- // BUG-FIX FOR ATTEMPTS HERE (OTHERWISE THIS FUNCTION IS THE SAME AS THE BASE IMPLEMENTATION):
482- 'attempts ' => $ payload ['attempts ' ],
483- 'priority ' => empty ($ payload ['priority ' ]) ? null : $ payload ['priority ' ],
484- ];
466+ 'data ' => [
467+ 'commandName ' => $ job ,
468+ 'command ' => $ job ,
469+ ],
470+ ]);
471+
472+ return array_merge ($ payload , [
473+ 'data ' => array_merge ([
474+ 'commandName ' => get_class ($ job ),
475+ 'command ' => serialize (clone $ job ),
476+ ],$ this ->getCustomMessageOptions ()),
477+ ]);
485478 }
486479}
0 commit comments