Manage job batches efficiently with Bus::batch in Laravel

Manage job batches efficiently with Bus::batch in Laravel

Handling multiple jobs in an application can sometimes be challenging, especially when you need to manage a group of jobs together. Laravel provides a robust solution with the Bus::batch method, allowing you to group multiple jobs into a batch and handle them collectively. This feature is particularly useful for processing large data sets, sending bulk emails, or performing operations that depend on multiple tasks.

Understanding Bus::batch

The Bus::batch method in Laravel allows you to dispatch a group of jobs as a single batch. This means you can track the progress of the entire batch, handle completion callbacks, and manage failures more effectively. Batching jobs helps improve the organization and efficiency of your queued tasks, making it easier to handle complex workflows.

Basic Usage

Here’s a basic example to illustrate how Bus::batch works:

use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Throwable;

Bus::batch([
    new ProcessOrder(1),
    new SendInvoice(1),
    new NotifyUser(1),
])->then(function (Batch $batch) {
    // All jobs completed successfully
})->catch(function (Batch $batch, Throwable $e) {
    // First job failure detected
})->finally(function (Batch $batch) {
    // The batch has finished executing
})->dispatch();

In this example, three jobs are dispatched as a single batch. The then, catch, and finally methods provide callbacks for handling different stages of the batch lifecycle.

Real-Life Example

Consider a scenario where you have an e-commerce platform, and you need to process orders, send invoices, and notify users about their orders. Using Bus::batch, you can handle these tasks collectively:

  1. Creating the Jobs:
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

    public $orderId;

    public function __construct($orderId)
    {
        $this->orderId = $orderId;
    }

    public function handle()
    {
        // Process the order
    }
}

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

    public $orderId;

    public function __construct($orderId)
    {
        $this->orderId = $orderId;
    }

    public function handle()
    {
        // Send the invoice
    }
}

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

    public $orderId;

    public function __construct($orderId)
    {
        $this->orderId = $orderId;
    }

    public function handle()
    {
        // Notify the user
    }
}
  1. Dispatching the Batch:
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Throwable;

Bus::batch([
    new ProcessOrder($orderId),
    new SendInvoice($orderId),
    new NotifyUser($orderId),
])->then(function (Batch $batch) {
    // All jobs completed successfully
    Log::info('All jobs in the batch completed successfully.');
})->catch(function (Batch $batch, Throwable $e) {
    // First job failure detected
    Log::error('A job in the batch failed.', ['error' => $e->getMessage()]);
})->finally(function (Batch $batch) {
    // The batch has finished executing
    Log::info('The batch has finished executing.');
})->dispatch();

In this example, the ProcessOrder, SendInvoice, and NotifyUser jobs are dispatched as a single batch. The callbacks handle the different stages of the batch, providing logging for success, failure, and completion.

Pro Tip

Use the allowFailures method if you want the batch to continue processing even if some jobs fail:

Bus::batch([
    new ProcessOrder($orderId),
    new SendInvoice($orderId),
    new NotifyUser($orderId),
])->allowFailures()->dispatch();

This approach ensures that all jobs in the batch are attempted, even if some fail, giving you greater flexibility in managing your tasks.

Conclusion

The Bus::batch method in Laravel is a powerful tool for managing groups of jobs efficiently. By leveraging this feature, you can streamline your job processing workflows, handle failures more gracefully, and improve the overall performance of your queued tasks.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe