Extend/Override Laravel Queues

Pratik Joshi
3 min readAug 12, 2020

--

Laravel is simple yet complex internally yet elegant and easily customizable.

Recently I had a scenario wherein I would need 2 more columns in jobs table and values need to be inserted when job is created. By default you cant insert values in the new columns so laravel code has to be modified.

Now that you are not going to modify vendor folder, you have to come up with your own classes inherited from Laravel framework’s classes.

Well lets get to the practical as who likes too much theory! :)

1 . Modify config/app.php : You see this line that shows QueueServiceProvider being included. Include our class instead by commenting/removing the line:

Old :

Illuminate\Queue\QueueServiceProvider::class,

New :

App\Providers\CustomQueueServiceProvider::class,

2. Add app/Providers/CustomQueueServiceProvider.php file with your own connector.

<?php

namespace App\Providers;

use App\Queue\Connectors\CustomDatabaseConnector;
use Illuminate\Queue\QueueServiceProvider;

class CustomQueueServiceProvider extends QueueServiceProvider
{
/**
* Register the database queue connector.
*
@NOTE:-This will be called automatically. We override DatabaseConnector,registerRedisConnector method so that we can add custom code. Will add custom as well
*
@param \Illuminate\Queue\QueueManager $manager
*
@return void
*/
protected function registerDatabaseConnector($manager)
{
$manager->addConnector('database', function () {
return new CustomDatabaseConnector($this->app['db']);
});
}

}

Here if you see I use CustomDatabaseConnector in registerDatabaseConnector by overriding the method. Note that we inherited class QueueServiceProvider to get all its original methods.

3. Add app/Queue/Connectors/CustomDatabaseConnector.php with your own connect method, CustomDatabaseQueue class.

<?php

namespace App\Queue\Connectors;

use App\Queue\CustomDatabaseQueue;
use Illuminate\Queue\Connectors\DatabaseConnector;

class CustomDatabaseConnector extends DatabaseConnector
{
/**
* Establish a queue connection.
*
*
@param array $config
*
@return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new CustomDatabaseQueue(
$this->connections->connection($config['connection'] ?? null),
$config['table'],
$config['queue'],
$config['retry_after'] ?? 60
);
}
}

4. Add app/Queue/CustomDatabaseQueue.php to have custom buildDatabaseRecord method.

<?php

namespace App\Queue;

use Illuminate\Queue\DatabaseQueue;
use Throwable;
use Illuminate\Support\Carbon;
use Illuminate\Database\Connection;
use Illuminate\Queue\Jobs\DatabaseJob;
use Illuminate\Queue\Jobs\DatabaseJobRecord;
use Illuminate\Contracts\Queue\Queue as QueueContract;
use Auth;

class CustomDatabaseQueue extends DatabaseQueue
{
/**
* Create an array to insert for the given job.
*
@Note:- Overriding to add custom field : logged in user id
*
*
@param string|null $queue
*
@param string $payload
*
@param int $availableAt
*
@param int $attempts
*
@return array
*/
protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0)
{
return [
'queue' => $queue,
'attempts' => $attempts,
'reserved_at' => null,
'available_at' => $availableAt,
'created_at' => $this->currentTime(),
'payload' => $payload,
'user_id' => Auth::user() ? Auth::user()->id : null,
'process_id' => getmypid(),
];
}
}

We inherit from DatabaseQueue and override only 1 method, rest of the methods come from parent class.

Note the line that sets values of user_id,process_id above.

This is our custom functionality. This is just one of the things I needed. We can rewrite & customize whole functionality just by overriding methods we need to modify.

This is one of the reasons why I love Laravel so much! That’s it for today, see you soon :) . Stay safe in pandemic!

--

--

Pratik Joshi

Sr. Software engineer by profession, problem solver by heart! I am here https://www.instagram.com/pratik.c.joshi/, or email me nutandevjoshi@gmail.com & say Hi!