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

Walkthrough

Space play step click any line
Three takeaways
  1. 1Implementing ShouldBeUnique with a stable uniqueId prevents the same work from being queued twice.
  2. 2Type-hinting a service in handle lets the queue worker resolve dependencies for you.
  3. 3Constructor property promotion keeps job payloads compact and serializable.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building a unique queued job in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code