php
47 lines · 7 steps
Building a unique queued job in Laravel
A queued Laravel job that renders a monthly report to storage and guards against duplicate runs.
Explained by
highlit
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Report;
6use App\Services\ReportBuilder;
7use Illuminate\Bus\Queueable;
8use Illuminate\Contracts\Queue\ShouldBeUnique;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Bus\Dispatchable;
11use Illuminate\Queue\InteractsWithQueue;
12use Illuminate\Queue\SerializesModels;
13use Illuminate\Support\Facades\Storage;
14
15class GenerateMonthlyReport implements ShouldQueue, ShouldBeUnique
16{
17 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
18
19 public int $uniqueFor = 3600;
20
21 public function __construct(
22 public Report $report,
23 public string $period,
24 ) {
25 }
26
27 public function uniqueId(): string
28 {
29 return $this->report->getKey().':'.$this->period;
30 }
31
32 public function handle(ReportBuilder $builder): void
33 {
34 $contents = $builder->for($this->report)
35 ->period($this->period)
36 ->render();
37
38 $path = "reports/{$this->report->getKey()}/{$this->period}.pdf";
39
40 Storage::disk('reports')->put($path, $contents);
41
42 $this->report->update([
43 'last_generated_at' => now(),
44 'latest_path' => $path,
45 ]);
46 }
47}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Implementing ShouldBeUnique with a stable uniqueId prevents the same work from being queued twice.
- 2Type-hinting a service in handle lets the queue worker resolve dependencies for you.
- 3Constructor property promotion keeps job payloads compact and serializable.
Related explainers
typescript
import { Injectable, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { ConfigService } from '@nestjs/config';
How a JWT strategy authenticates in NestJS
authentication
jwt
passport
Intermediate
7 steps
php
<?php namespace App\Http\Controllers;
Streaming a filtered CSV export in Laravel
streaming
csv-export
query-builder
Intermediate
9 steps
php
<?php namespace App\Http\Middleware;
Idempotent requests with Laravel middleware
idempotency
middleware
caching
Advanced
8 steps
python
import os from datetime import timedelta
Class-based config in a Flask app factory
configuration
app-factory
inheritance
Intermediate
7 steps
php
<?php namespace App\Services;
Batch image resizing with PHP GD
image-processing
constructor-promotion
match-expression
Intermediate
10 steps
typescript
import { Injectable, Logger, OnApplicationShutdown } from '@nestjs/common'; import { InjectRedis } from '@nestjs-modules/ioredis'; import Redis from 'ioredis'; import { DataSource } from 'typeorm';
Graceful shutdown hooks in NestJS
graceful-shutdown
lifecycle-hooks
dependency-injection
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/building-a-unique-queued-job-in-laravel-explained-php-e2b1/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.