Laravel Queue: Job Class demystified (ShouldQueue, Dispatchable, InteractsWithQueue, Queueable, SerializesModels)

Laravel is awesome, but personally I don’t appreciate their documentation as it seems always “beginner orientated”.

They trend make simple things automagically happen, without let you knowing how it works.

They you get into trouble when you need advanced functionality.

Say, you get this boilerplate when typing php artisan make:job TestJob:

<?php

namespace App\Jobs;

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

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

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}

So, what actually are ShouldQueue, Dispatchable, InteractsWithQueue, Queueable, SerializesModels?
Documentation won’t tell you, even if you read the API Reference, you have little idea what they means.

Actually, the bare minimal Job code you need is:

<?php

namespace App\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;

class TestJob implements ShouldQueue
{
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

    }
}

So what are those Contracts and Traits? Let’s explain them one by one.

  • ShouldQueue interface – A Laravel Contract (i.e. PHP Interface without functionality)Which is checked against by Illuminate/Bus/Dispatcher,To decide if this Job should be “dispatched now” (Run in same process), or “dispatched to queue” (Wait for worker to pickup)Without implementing this Contract, the Job will be dispatched (i.e. executed) intermediately.YES, you are required to implement this interface to use Queue.
  • Dispatchable trait
    Provide methods that the Job’s dispatcher can use the following syntax:
    $job->dispatch();
    $job->broadcast();
    NO, you are not required to use this trait to use Queue.
    Those methods are totally optional.
    You can always dispatch a job via helper function: dispatch($job)
  • InteractsWithQueue trait
    Provide methods that Job itself can interact with the queue it is on, including:
    Get current attempt
    Delete itself from queue
    Release itself back to queue and run later
    Mark itself as failed
    NO, you are not required to use this trait to use Queue.
    Those methods are totally optional.
  • Queueable trait
    Provide methods that the Job’s dispatcher can specify the following:
    Connection – $job->onConnection($connection)
    Queue – $job->onQueue($queue)
    Execution Delay – $job->delay($delay)
    NO, you are not required to use this trait to use Queue.
    Those methods are totally optional.
    If you want to specify those option in your Job class, you may not even want to use this trait.
  • SerializesModels trait
    Provide magic methods that change behavior how the Job’s Model properties during serialization/unserialization process.
    which is how Laravel Queue works internally – serialize Jobs into string, and store them in database/redis/sqs…etc
    If this trait is used, Laravel reread the model from database using it’s identifier when the Job actually run.
    For further explanations, please refer to: https://gistlog.co/JacobBennett/e60d6a932db98985f160146b09455988
    YES and NO, if you pass any Models in your Job’s constructor/setter, and want to use them in Job execution, you may want to use this trait.

2 Replies to “Laravel Queue: Job Class demystified (ShouldQueue, Dispatchable, InteractsWithQueue, Queueable, SerializesModels)”

Leave a Reply to Emil Kirilov Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.