Dispatching Jobs

Dispatching, Delaying, and Chaining Jobs

dispatch() returns a PendingDispatch, pushed when the statement ends, that takes onConnection(), onQueue('emails'), delay(now()->plus(minutes: 10)) and afterCommit(); dispatchIf() adds a condition and Bus::bulk() pushes many jobs at once. A chain runs jobs in order and stops at the first that fails for good, which suits checkout:

A checkout chain in routes/console.phpPHP
Artisan::command('shop:checkout {order}', function (int $order) {
    $order = Order::findOrFail($order);
    Bus::chain([
        new GenerateInvoice($order),
        new SendOrderConfirmation($order),
        (new NotifyWarehouse($order))->delay(now()->plus(seconds: 5)),
    ])->catch(function (Throwable $e) use ($order) {
        Log::error("checkout chain for order {$order->id} stopped: {$e->getMessage()}");
    })->dispatch();
    $this->info("order {$order->id}: chain of 3 jobs queued");
});

After php artisan shop:checkout 7, jobs held one row, GenerateInvoice; the rest of the chain rides in its payload. The worker finished the email at 08:57:54 and started the warehouse job at 08:58:00 (delay plus polling); with the warehouse down, its third failure ended the chain and fired catch. Chain callbacks are serialized from their source file; typed into tinker, the same chain failed with Call to a member function bindTo() on null.