<?php
namespace App\Jobs;
use App\Models\Podcast;
use App\Services\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 3;
public $timeout = 300; // 5 minutes
public function __construct(
public Podcast $podcast
) {}
public function handle(AudioProcessor $processor): void
{
// Process the podcast audio
$processor->normalize($this->podcast->file_path);
$processor->generateWaveform($this->podcast);
$processor->extractMetadata($this->podcast);
// Update podcast status
$this->podcast->update(['status' => 'processed']);
// Dispatch follow-up job
GeneratePodcastTranscript::dispatch($this->podcast);
}
public function backoff(): array
{
return [60, 300, 900]; // 1 min, 5 min, 15 min
}
public function failed(\Throwable $exception): void
{
// Notify admins of failure
$this->podcast->update(['status' => 'failed']);
\Log::error('Podcast processing failed', [
'podcast_id' => $this->podcast->id,
'error' => $exception->getMessage(),
]);
}
}
<?php
// Dispatch job immediately
ProcessPodcast::dispatch($podcast);
// Dispatch job to specific queue
ProcessPodcast::dispatch($podcast)->onQueue('processing');
// Delay job execution
ProcessPodcast::dispatch($podcast)->delay(now()->addMinutes(10));
// Job chaining
\Illuminate\Support\Facades\Bus::chain([
new ProcessPodcast($podcast),
new GeneratePodcastTranscript($podcast),
new NotifySubscribers($podcast),
])->dispatch();
// Job batching
\Illuminate\Support\Facades\Bus::batch([
new ProcessPodcast($podcast1),
new ProcessPodcast($podcast2),
new ProcessPodcast($podcast3),
])->then(function (\Illuminate\Bus\Batch $batch) {
// All jobs completed successfully
})->catch(function (\Illuminate\Bus\Batch $batch, \Throwable $e) {
// First batch job failure
})->finally(function (\Illuminate\Bus\Batch $batch) {
// Batch completed
})->dispatch();
Queues offload time-consuming tasks to background workers, keeping web requests fast. I create job classes that implement the ShouldQueue interface and define a handle() method. Jobs are dispatched with dispatch() or Job::dispatch() and run asynchronously via queue workers. The tries property limits retry attempts, while backoff() defines exponential backoff between retries. Failed jobs go to a failed jobs table for manual inspection. I use onQueue() to route jobs to specific queues—high-priority jobs to a dedicated queue. Job chaining with Bus::chain() runs jobs sequentially, while batching groups related jobs. The queue system supports multiple drivers: database, Redis, SQS, or Beanstalkd. This architecture handles millions of jobs reliably.