lastdragon-ru/lara-asp-queue

This package is abandoned and no longer maintained. The author suggests using the lastdragon-ru/lara-asp-core package instead.

The Awesome Set of Packages for Laravel - Queue Helpers.

5.6.0 2024-02-16 07:58 UTC

README

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.

Warning

The package is marked as deprecated because of its complexity and support difficulties. Please use the core package instead, that provides similar but simplified features.

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

  1. Run

     composer require lastdragon-ru/lara-asp-queue
  2. 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> from config/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.