Queue Helpers
This package provides additional capabilities for queued jobs and queued listeners like multilevel configuration support, job overriding (very useful for package development to provide base implementation and allow the application to extend it), easy define for cron jobs, and DI in constructor support.
Requirements
Requirement | Constraint | Supported by |
---|---|---|
PHP | ^8.3 |
HEAD ⋯ 5.0.0 |
^8.2 |
HEAD ⋯ 2.0.0 |
|
^8.1 |
HEAD ⋯ 2.0.0 |
|
^8.0 |
4.6.0 ⋯ 2.0.0 |
|
^8.0.0 |
1.1.2 ⋯ 0.12.0 |
|
>=8.0.0 |
0.11.0 ⋯ 0.4.0 |
|
>=7.4.0 |
0.3.0 ⋯ 0.1.0 |
|
Laravel | ^10.0.0 |
HEAD ⋯ 2.1.0 |
^9.21.0 |
HEAD ⋯ 5.0.0-beta.1 |
|
^9.0.0 |
5.0.0-beta.0 ⋯ 0.12.0 |
|
^8.22.1 |
3.0.0 ⋯ 0.2.0 |
|
^8.0 |
0.1.0 |
Installation
-
Run
composer require lastdragon-ru/lara-asp-queue
-
Overwrite default event Dispatcher by adding following code into
bootstrap/app.php
(before all others singletons):$app->singleton('events', \LastDragon_ru\LaraASP\Queue\EventsDispatcher::class);
This is required if you want use configuration/DI for queued Listeners. Please see laravel/framework#25272 for reason.
Configuration
To add the configuration for job/listener/mailable you just need extends one the base classes:
<?php declare(strict_types = 1);
namespace App\Jobs;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Date;
use LastDragon_ru\LaraASP\Core\Utils\Cast;
use LastDragon_ru\LaraASP\Queue\QueueableConfigurator;
use LastDragon_ru\LaraASP\Queue\Queueables\Job;
use Override;
class MyJobWithConfig extends Job {
/**
* Default config.
*
* @inheritDoc
*/
#[Override]
public function getQueueConfig(): array {
return [
'queue' => 'queue',
'settings' => [
'expire' => '18 hours',
],
] + parent::getQueueConfig();
}
public function __invoke(QueueableConfigurator $configurator): void {
// This is how we can get access to the actual config inside `handle`
$config = $configurator->config($this);
$expire = Cast::toString($config->setting('expire'));
$expire = Date::now()->sub($expire);
Model::query()
->where('updated_at', '<', $expire)
->delete();
}
}
Configurations have the following priority (last win):
- own properties (
$this->connection
,$this->queue
, etc) - own config from
getQueueConfig()
- app's config (
queue.queueables.<class>
fromconfig/queue.php
if present) onConnection()
,onQueue()
, etc calls
Thus, you can easily set settings for your jobs in app config, for example, we can set the expire
setting on 8 hours
:
<?php declare(strict_types = 1);
use App\Jobs\MyJobWithConfig;
// config/queue.php
return [
// .....
/*
|--------------------------------------------------------------------------
| Queueables Configuration
|--------------------------------------------------------------------------
|
| These options configure the behavior of custom queue jobs.
|
*/
'queueables' => [
MyJobWithConfig::class => [
'settings' => [
'expire' => '8 hours',
],
],
],
];
Cron jobs
Creating the cron jobs is similar. They just have two additional settings:
<?php declare(strict_types = 1);
namespace App\Jobs;
use LastDragon_ru\LaraASP\Queue\Queueables\CronJob;
use Override;
class MyCronJob extends CronJob {
/**
* @inheritDoc
*/
#[Override]
public function getQueueConfig(): array {
return [
'cron' => '0 * * * *', // Cron expression
'enabled' => true, // Status (`false` will disable the job)
] + parent::getQueueConfig();
}
public function __invoke(): void {
// ....
}
}
But the registration of the jobs a slightly different. For Kernel
you should use following way:
<?php declare(strict_types = 1);
namespace App\Console;
use App\Jobs\MyCronJob;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use LastDragon_ru\LaraASP\Queue\Concerns\ConsoleKernelWithSchedule;
use LastDragon_ru\LaraASP\Queue\Contracts\Cronable;
use Override;
use function base_path;
class Kernel extends ConsoleKernel {
// !!! Add this trait
use ConsoleKernelWithSchedule;
// !!! Add this property and put all cron jobs inside
/**
* The application's command schedule.
*
* @var list<class-string<Cronable>>
*/
protected array $schedule = [
MyCronJob::class,
];
/**
* Register the commands for the application.
*/
#[Override]
protected function commands(): void {
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
And for package providers:
<?php declare(strict_types = 1);
namespace LastDragon_ru\LaraASP\Migrator;
use App\Jobs\MyCronJob;
use Illuminate\Support\ServiceProvider;
use LastDragon_ru\LaraASP\Queue\Concerns\ProviderWithSchedule;
class Provider extends ServiceProvider {
use ProviderWithSchedule;
public function boot(): void {
$this->bootSchedule(
// Put all cron jobs provided in the package here
MyCronJob::class,
);
}
}
Finally, the package also discloses all settings in the job description:
$ php artisan schedule:list
+---------+-------------+------------------------------------------------------------------------+---------------------+
| Command | Interval | Description | Next Due |
+---------+-------------+------------------------------------------------------------------------+---------------------+
| | 0 0 * * * | App\Jobs\JobsCleanupCronJob | 2021-03-14 00:00:00 |
| | | {"queue":"default","enabled":true,"settings":{"expire":"18 hours"}} | |
| | */5 * * * * | App\Jobs\SiteLogsCleanupCronJob | 2021-03-13 06:40:00 |
| | | {"queue":"default","enabled":true,"settings":{"expire":"30 days"}} | |
+---------+-------------+------------------------------------------------------------------------+---------------------+
Overriding package Jobs
The most interesting and useful thing for package developers is the ability to extend all package's jobs in the application. For example, our package provides the DoSomethingPackageJob
, its settings can be easily changed through the config, but can we extend it in the app? Yes!
First, we are no need additional actions for CronJob
, but should use Container::make()
for Job
and Mails
:
<?php declare(strict_types = 1);
use Illuminate\Container\Container;
use Package\Jobs\DoSomethingPackageJob;
// Use
Container::getInstance()->make(DoSomethingPackageJob::class)->dispatch();
// Instead of
// @phpstan-ignore-next-line
DoSomethingPackageJob::dispatch();
then inside the app
<?php declare(strict_types = 1);
namespace App\Jobs;
use Override;
use Package\Jobs\DoSomethingPackageJob;
class DoSomethingAppJob extends DoSomethingPackageJob {
#[Override]
public function __invoke(): void {
// our implementation
}
}
and finally, register it:
<?php declare(strict_types = 1);
namespace App\Providers;
use App\Jobs\DoSomethingAppJob;
use Illuminate\Support\ServiceProvider;
use Override;
use Package\Jobs\DoSomethingPackageJob;
class AppServiceProvider extends ServiceProvider {
/**
* Register any application services.
*/
#[Override]
public function register(): void {
$this->app->bind(DoSomethingAppJob::class, DoSomethingPackageJob::class);
}
}
🥳
The CustomUpdateSomethingJob
will use the same settings name in config/queue.php
as UpdateSomethingJob
. Sometimes you may want to create a new job with its own config, in this case, you should break the config chain:
<?php declare(strict_types = 1);
namespace App\Jobs;
use LastDragon_ru\LaraASP\Queue\Concerns\WithConfig;
use Override;
use Package\Jobs\DoSomethingPackageJob;
class DoSomethingAppJob extends DoSomethingPackageJob {
use WithConfig; // Indicates that the job has its own config
#[Override]
public function __invoke(): void {
// our implementation
}
}
Contributing
This package is the part of Awesome Set of Packages for Laravel. Please use the main repository to report issues, send pull requests, or ask questions.