Example Job Format for Queue

Posted: 2017-01-14 23:22:41

Sometimes I just need this info to remind myself what a job looks like in a queue and how to mock it etc.

In this case I have a simple class that will be used to dispatch the job.

<?php

namespace App\Jobs;

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

class RandomWordJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    public $payload = [];

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

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::debug("Here", [var_dump($this->payload)]);
        dd($this->payload);
    }
}

Notice, in this case I put an array payload into the constructor. And it is public because I want to be passed into the queue.

What the payload in the queue will look like is this

{"job":"Illuminate\\Queue\\CallQueuedHandler@call","data":{"commandName":"App\\Jobs\\RandomWordJob","command":"O:22:\"App\\Jobs\\RandomWordJob\":5:{s:7:\"payload\";a:2:{s:11:\"word_number\";i:28;s:17:\"destination_queue\";s:20:\"docker-words-private\";}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";s:8:\"requests\";s:5:\"queue\";N;s:5:\"delay\";N;}"}}

Serialized data.

For a quick example of making this happen I made an Artisan command just to put job(s) into the queue so I can see this and maybe for fun just see the whole process through (but honestly it is best to mock the queue and know your class will work if the payload is right) more on that in a moment.

<?php

namespace App\Console\Commands;

use App\Jobs\RandomWordJob;
use Illuminate\Console\Command;

class PutSampleRequestInQueue extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'docker-work:sample-request';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Put a sample request into the right queue';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $payload = [
            'word_number' => random_int(1, 100),
            'destination_queue' => "docker-words-private"
        ];

        $job = (new RandomWordJob($payload))->onConnection('requests');

        dispatch($job);
    }
}

From here I can now run php artisan queue:work requests --once to see my class get this job and "process it"

Testing

But now for ease of testing this Job Class I can just do this.

    /**
     * @test
     */
    public function process_payload_make_word_count_and_destination_in_payload()
    {

        //Should get the number
        //make a word
        //make a payload to put back into the queue
        $payload = [
            'word_number' => random_int(1, 100),
            'destination_queue' => "docker-words-private"
        ];

        $job = new \App\Jobs\RandomWordJob($payload);

        $job->handle();

        PHPUnit_Framework_Assert::assertNotNull($job->getResults());
    }

In this case I will store some results of the process, since it is not saved in a databse for this example, in the object and then in my test prove the class did what it was suppose to do.

Basically I know Laravel works, I know SQS works, and I know how the data will be handed to the class as it is instantiated so I am just testing the Class and how it handles the request.

Note too like a Controller it is really key to handle inside a Try/Catch

    public function handle()
    {
        try {
            Log::debug("Here", [var_dump($this->payload)]);
            dd($this->payload);
        } catch (\Exception $e) {
            Log::debug(sprintf("Failed to work :( %s", $e->getMessage()));
        }
    }