Skip to content

Commit 09573b1

Browse files
committed
+ custom queued handler
1 parent 05c6578 commit 09573b1

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

README.md

+28
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,34 @@ Please make sure that two special routes are not mounted behind a CSRF middlewar
185185
If your job fails, we will throw a ```FailedJobException```. If you want to customize error output – just customise your exception handler.
186186
Note that your HTTP status code must be different from 200 in order for AWS to realize the job has failed.
187187

188+
## Job expiration (retention)
189+
190+
A new nice feature is being able to set a job expiration (retention in AWS terms) in seconds so
191+
that low value jobs get skipped completely if there is temporary queue latency due to load.
192+
193+
Let's say we have a spike in queued jobs and some of them don't even make sense anymore
194+
now that a few minutes passed – we don't want to spend computing resources processing them
195+
later.
196+
197+
By setting a special property on a job or a listener class:
198+
```php
199+
class PurgeCache implements ShouldQueue
200+
{
201+
public static int $retention = 300; // If this job is delayed more than 300 seconds, skip it
202+
}
203+
```
204+
205+
We can make sure that we won't run this job later than 300 seconds since it's been queued.
206+
This is similar to AWS SQS "message retention" setting which can only be set globally for
207+
the whole queue.
208+
209+
To use this new feature, you have to use provided ```Jobs\CallQueuedHandler``` class that
210+
extends Laravel's default ```CallQueuedHandler```. A special ```ExpiredJobException``` exception
211+
will be thrown when expired jobs arrive and then it's up to you what to do with them.
212+
213+
If you just catch these exceptions and therefore stop Laravel from returning code 500
214+
to AWS daemon, the job will be deleted by AWS automatically.
215+
188216
## ToDo
189217

190218
1. Add support for AWS dead letter queue (retry jobs from that queue?)
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
namespace Dusterio\AwsWorker\Exceptions;
4+
5+
class ExpiredJobException extends \Exception {
6+
}

src/Jobs/CallQueuedHandler.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Dusterio\AwsWorker\Jobs;
4+
5+
use Dusterio\AwsWorker\Exceptions\ExpiredJobException;
6+
use Illuminate\Contracts\Queue\Job;
7+
use Illuminate\Queue\CallQueuedHandler as LaravelHandler;
8+
9+
class CallQueuedHandler extends LaravelHandler {
10+
/**
11+
* Dispatch the given job / command through its specified middleware.
12+
*
13+
* @param \Illuminate\Contracts\Queue\Job $job
14+
* @param mixed $command
15+
* @return mixed
16+
*/
17+
protected function dispatchThroughMiddleware(Job $job, $command)
18+
{
19+
if ($this->hasExpired($command, $job->timestamp())) {
20+
throw new ExpiredJobException("This job has already expired");
21+
}
22+
23+
return parent::dispatchThroughMiddleware($job, $command);
24+
}
25+
26+
/**
27+
* @param $command
28+
* @param $queuedAt
29+
* @return bool
30+
*/
31+
protected function hasExpired($command, $queuedAt) {
32+
if (! property_exists($command, 'class')) {
33+
return false;
34+
}
35+
36+
if (! property_exists($command->class, 'retention')) {
37+
return false;
38+
}
39+
40+
return time() > $queuedAt + $command->class::$retention;
41+
}
42+
}

0 commit comments

Comments
 (0)