Install the laravel-queueable-action package
mainInstall the package via Composer to add support for queueable actions to your Laravel application.
composer require spatie/laravel-queueable-actionrepository·main·Indexed 20 days ago
https://github.com/spatie/laravel-queueable-actionA Laravel package for structuring business logic using Actions that can be executed synchronously or dispatched to queues. It supports constructor injection via the Laravel container, invokeable actions, action chaining via ActionJob, and custom Horizon tags and job middleware.
Install the package via Composer to add support for queueable actions to your Laravel application.
composer require spatie/laravel-queueable-actionYou can optionally publish the configuration file to customize the job class used for dispatching actions. If you provide a custom job class, it must extend \Spatie\QueueableAction\ActionJob.
php artisan vendor:publish --provider="Spatie\QueueableAction\QueueableActionServiceProvider" --tag="config"You can chain multiple actions together by wrapping subsequent actions in an ActionJob. The ActionJob constructor accepts the action class (or instance) as the first argument and an array of the action's arguments as the second.
use Spatie\QueueableAction\ActionJob;
$args = [$userId, $data];
app(MyAction::class)
->onQueue()
->execute(...$args)
->chain([
new ActionJob(AnotherAction::class, $args),
]);Once an action is defined with the QueueableAction trait, you can choose to run it immediately or dispatch it to a queue.
execute() directly.onQueue() followed by execute().onQueue('queue-name').// Execute on the default queue
$action->onQueue()->execute($model, $requestData);
// Execute on a specific queue
$action->onQueue('my-favorite-queue')->execute($model, $requestData);
// Execute synchronously (right now)
$action->execute($model, $requestData);To create an action, use the QueueableAction trait. You can use the Artisan command to generate these classes automatically. Actions can use standard methods (like execute()) or the __invoke() magic method. Constructor arguments are resolved from the Laravel container.
php artisan make:action MyAction [--sync]class MyAction
{
use QueueableAction;
public function __construct(
OtherAction $otherAction,
ServiceFromTheContainer $service
) {
$this->otherAction = $otherAction;
$this->service = $service;
}
public function execute(
MyModel $model,
RequestData $requestData
) {
// Business logic
}
}The package automatically detects actions that implement the __invoke() method. To queue an invokeable action, you still use the onQueue()->execute() pattern.
class MyInvokeableAction
{
use QueueableAction;
public function __invoke(
MyModel $model,
RequestData $requestData
) {
// Business logic
}
}
// To queue it:
$myInvokeableAction->onQueue()->execute($model, $requestData);Use Spatie\QueueableAction\Testing\QueueableActionFake to assert that actions were pushed to the queue. Note: You must call Queue::fake() before using these assertions.
/** @test */
public function it_queues_an_action()
{
Queue::fake();
(new DoSomethingAction)->onQueue()->execute();
QueueableActionFake::assertPushed(DoSomethingAction::class);
}To change the tags that appear in Laravel Horizon for a specific action, override the tags() method within your action class.
class CustomTagsAction
{
use QueueableAction;
public function tags()
{
return ['action', 'custom_tags'];
}
}You can define how long Laravel should wait before retrying an action that fails. You can do this by defining a $backoff property or a backoff() method.
// Using a property
class BackoffAction
{
use QueueableAction;
public $backoff = 3;
}
// Using a method for complex logic
class BackoffAction
{
use QueueableAction;
public function backoff(): int
{
return 3;
}
}
// Using an array for exponential backoff
class BackoffAction
{
use QueueableAction;
public function backoff(): array
{
return [1, 5, 10]; // 1s, then 5s, then 10s
}
}You can apply middleware to the job that handles your action by overriding the middleware() method in your action class.
class CustomTagsAction
{
use QueueableAction;
public function middleware()
{
return [new RateLimited()];
}
}The following assertions are available in the QueueableActionFake class for testing action dispatching.
QueueableActionFake::assertPushed(string $actionClass);
QueueableActionFake::assertPushedTimes(string $actionClass, int $times = 1);
QueueableActionFake::assertNotPushed(string $actionClass);
QueueableActionFake::assertPushedWithChain(string $actionClass, array $expextedActionChain = []);
QueueableActionFake::assertPushedWithoutChain(string $actionClass);Use the make:action Artisan command to scaffold a new action class. By default, the command generates a queued action class located in the App\Actions namespace. If you want the action to be synchronous (not queued), use the --sync flag.
php artisan make:action MyNewAction
# To create a synchronous action instead of a queued one:
php artisan make:action MySyncAction --sync