Skip to content
Acorn

Help us continue to build and maintain our open source projects. We’re a small team of independent developers and every little bit helps.

Creating and Processing Laravel Queues

View as Markdown:

Acorn brings Laravel's robust queue system to WordPress, enabling you to defer time-consuming tasks like image processing, email sending, or API calls to background jobs. This improves your application's response time and user experience by handling heavy operations asynchronously.

We recommend referencing the Laravel docs on Queues for a complete understanding of the queue system.

Setting up the queue system

Before you can start using queues, you need to create the necessary database tables to store jobs and track their status.

1. Generate queue tables

Create the migration files for queue functionality:

Generate the jobs table migration

$ wp acorn queue:table

Generate the job batches table (optional, for batch processing)

$ wp acorn queue:batches-table

2. Run migrations

Apply the migrations to create the required tables:

$ wp acorn migrate

This will create:

  • A jobs table to store queued jobs
  • A job_batches table for batch job processing (if generated)
  • A failed_jobs table to track failed job attempts

Creating your first job

To create a new job class, use the make:job command:

$ wp acorn make:job ProcessImageOptimization

This creates a new job file in app/Jobs/ with the basic structure needed for a queue job.

Job file structure

A typical job class contains several key components:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class ProcessImageOptimization implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Number of times the job may be attempted
     */
    public $tries = 3;

    /**
     * Number of seconds to wait before retrying
     */
    public $backoff = [30, 60, 120];

    /**
     * Number of seconds the job can run before timing out
     */
    public $timeout = 180;

    /**
     * The attachment ID to process
     */
    protected int $attachmentId;

    /**
     * Create a new job instance
     */
    public function __construct(int $attachmentId)
    {
        $this->attachmentId = $attachmentId;
    }

    /**
     * Execute the job
     */
    public function handle(): void
    {
        Log::info("Processing image optimization for attachment: {$this->attachmentId}");

        $attachment = get_post($this->attachmentId);

        if (!$attachment || $attachment->post_type !== 'attachment') {
            Log::error("Invalid attachment ID: {$this->attachmentId}");
            return;
        }

        $file_path = get_attached_file($this->attachmentId);

        // Your image optimization logic here
        // For example, using an image optimization library

        // Mark as processed using post meta
        update_post_meta($this->attachmentId, '_processed', true);
        update_post_meta($this->attachmentId, '_processed_at', current_time('timestamp'));

        Log::info("Successfully optimized image: {$this->attachmentId}");
    }

    /**
     * Handle a job failure
     */
    public function failed(\Throwable $exception): void
    {
        Log::error("Failed to optimize image {$this->attachmentId}: {$exception->getMessage()}");

        // Notify administrators or take other actions
    }
}

Dispatching jobs

Once you've created a job, you can dispatch it from anywhere in your application:

Basic dispatching

use App\Jobs\ProcessImageOptimization;

// Dispatch a job to the default queue
ProcessImageOptimization::dispatch($attachmentId);

// Dispatch with a delay
ProcessImageOptimization::dispatch($attachmentId)
    ->delay(now()->addMinutes(5));

// Dispatch to a specific queue
ProcessImageOptimization::dispatch($attachmentId)
    ->onQueue('images');

WordPress hook integration

Integrate queue jobs with WordPress hooks for automatic processing:

// In your theme's functions.php or a service provider
add_action('add_attachment', function ($attachmentId) {
    \App\Jobs\ProcessImageOptimization::dispatch($attachmentId);
});

// Process form submissions asynchronously
add_action('gform_after_submission', function ($entry, $form) {
    \App\Jobs\ProcessFormSubmission::dispatch($entry['id']);
}, 10, 2);

Processing queued jobs

To process jobs in the queue, you need to run a queue worker.

Running a queue worker

Process jobs continuously

$ wp acorn queue:work

Process jobs from a specific queue

$ wp acorn queue:work --queue=high,default

Process a single job and exit

$ wp acorn queue:work --once

Process jobs for a specific duration

$ wp acorn queue:work --stop-when-empty

Managing failed jobs

When jobs fail after all retry attempts, they're moved to the failed_jobs table.

View failed jobs

$ wp acorn queue:failed

Retry all failed jobs

$ wp acorn queue:retry all

Retry specific job

$ wp acorn queue:retry 5

Retry multiple jobs

$ wp acorn queue:retry 5 6 7

Remove all failed jobs

$ wp acorn queue:flush

Remove a specific failed job

$ wp acorn queue:forget 5

Dispatching jobs

// In a controller or WordPress hook
use App\Jobs\ProcessImageOptimization;

// Dispatch immediately
ProcessImageOptimization::dispatch($attachmentId);

// Dispatch with delay
ProcessImageOptimization::dispatch($attachmentId)->delay(now()->addMinutes(5));

Last updated