php 48 lines · 7 steps

A retrying queue job in Laravel

A queued job that transcodes a podcast, retries on failure, and alerts Slack when it finally gives up.

Explained by highlit
1<?php
2 
3namespace App\Jobs;
4 
5use App\Notifications\SlackJobFailed;
6use Illuminate\Bus\Queueable;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Bus\Dispatchable;
9use Illuminate\Queue\InteractsWithQueue;
10use Illuminate\Queue\SerializesModels;
11use Illuminate\Support\Facades\Notification;
12use Illuminate\Support\Facades\Log;
13use Throwable;
14 
15class ProcessPodcastUpload implements ShouldQueue
16{
17 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
18 
19 public int $tries = 3;
20 public int $timeout = 120;
21 
22 public function __construct(public int $podcastId)
23 {
24 }
25 
26 public function handle(): void
27 {
28 $podcast = \App\Models\Podcast::findOrFail($this->podcastId);
29 
30 $podcast->transcode();
31 $podcast->markProcessed();
32 }
33 
34 public function failed(Throwable $exception): void
35 {
36 Log::error('Podcast processing failed', [
37 'podcast_id' => $this->podcastId,
38 'exception' => $exception->getMessage(),
39 ]);
40 
41 Notification::route('slack', config('services.slack.alerts_webhook'))
42 ->notify(new SlackJobFailed(
43 job: class_basename($this),
44 context: ['podcast_id' => $this->podcastId, 'attempts' => $this->attempts()],
45 exception: $exception,
46 ));
47 }
48}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Storing only an ID and re-fetching in handle keeps queued payloads small and always current.
  2. 2The tries and timeout properties bound retries and runtime without any extra wiring.
  3. 3A failed hook turns the last failure into observable signal — logs plus a human alert.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A retrying queue job in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code