Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/spatie/laravel-queueable-action
Queueable actions in Laravel
https://github.com/spatie/laravel-queueable-action
actions laravel queues
Last synced: 7 days ago
JSON representation
Queueable actions in Laravel
- Host: GitHub
- URL: https://github.com/spatie/laravel-queueable-action
- Owner: spatie
- License: mit
- Created: 2019-02-15T14:26:00.000Z (almost 6 years ago)
- Default Branch: main
- Last Pushed: 2024-09-20T13:06:22.000Z (4 months ago)
- Last Synced: 2025-01-07T20:06:45.133Z (14 days ago)
- Topics: actions, laravel, queues
- Language: PHP
- Homepage: https://spatie.be/open-source
- Size: 155 KB
- Stars: 654
- Watchers: 10
- Forks: 55
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
# Queueable actions in Laravel
[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-queueable-action.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-queueable-action)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-queueable-action/run-tests.yml?label=tests)
![Check & fix styling](https://github.com/spatie/laravel-queueable-action/workflows/Check%20&%20fix%20styling/badge.svg)
[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-queueable-action.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-queueable-action)Actions are a way of structuring your business logic in Laravel.
This package adds easy support to make them queueable.```php
$myAction->onQueue()->execute();
```You can specify a queue name.
```php
$myAction->onQueue('my-favorite-queue')->execute();
```## Support us
[](https://spatie.be/github-ad-click/laravel-queueable-action)
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
## Installation
You can install the package via composer:
```bash
composer require spatie/laravel-queueable-action
```You can optionally publish the config file with:
```bash
php artisan vendor:publish --provider="Spatie\QueueableAction\QueueableActionServiceProvider" --tag="config"
```This is the contents of the published config file:
```php
return [
/*
* The job class that will be dispatched.
* If you would like to change it and use your own job class,
* it must extends the \Spatie\QueueableAction\ActionJob class.
*/
'job_class' => \Spatie\QueueableAction\ActionJob::class,
];
```## Usage
If you want to know about the reasoning behind actions and their asynchronous usage,
you should read the dedicated blog post: [https://stitcher.io/blog/laravel-queueable-actions](https://stitcher.io/blog/laravel-queueable-actions).You can use the following Artisan command to generate queueable and synchronous action classes on the fly.
```
php artisan make:action MyAction [--sync]
```Here's an example of queueable actions in use:
``` php
class MyAction
{
use QueueableAction;public function __construct(
OtherAction $otherAction,
ServiceFromTheContainer $service
) {
// Constructor arguments can come from the container.$this->otherAction = $otherAction;
$this->service = $service;
}public function execute(
MyModel $model,
RequestData $requestData
) {
// The business logic goes here, this can be executed in an async job.
}
}
``````php
class MyController
{
public function store(
MyRequest $request,
MyModel $model,
MyAction $action
) {
$requestData = RequestData::fromRequest($myRequest);// Execute the action on the queue:
$action->onQueue()->execute($model, $requestData);// Or right now:
$action->execute($model, $requestData);
}
}
```The package also supports actions using the `__invoke()` method. This will be detected automatically. Here is an example:
``` php
class MyInvokeableAction
{
use QueueableAction;public function __invoke(
MyModel $model,
RequestData $requestData
) {
// The business logic goes here, this can be executed in an async job.
}
}
```The actions using the `__invoke()` method should be added to the queue the same way as explained in the examples above, by running the `execute()` method after the `onQueue()` method.
```php
$myInvokeableAction->onQueue()->execute($model, $requestData);
```### Testing queued actions
The package provides some test assertions in the `Spatie\QueueableAction\Testing\QueueableActionFake` class. You can use them in a PhpUnit test like this:
```php
/** @test */
public function it_queues_an_action()
{
Queue::fake();(new DoSomethingAction)->onQueue()->execute();
QueueableActionFake::assertPushed(DoSomethingAction::class);
}
```Don't forget to use `Queue::fake()` to mock Laravel's queues before using the `QueueableActionFake` assertions.
The following assertions are available:
```php
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)
```Feel free to send a PR if you feel any of the other `QueueFake` assertions are missing.
### Chaining actions
You can chain actions by wrapping them in the `ActionJob`.
Here's an example of two actions with the same arguments:
```php
use Spatie\QueueableAction\ActionJob;$args = [$userId, $data];
app(MyAction::class)
->onQueue()
->execute(...$args)
->chain([
new ActionJob(AnotherAction::class, $args),
]);
```The `ActionJob` takes the action class *or* instance as the first argument followed by an array of the action's own arguments.
### Custom Tags
If you want to change what tags show up in Horizon for your custom actions you can override the `tags()` function.
``` php
class CustomTagsAction
{
use QueueableAction;// ...
public function tags() {
return ['action', 'custom_tags'];
}
}
```### Job Middleware
Middleware where action job passes through can be added by overriding the `middleware()` function.
``` php
class CustomTagsAction
{
use QueueableAction;// ...
public function middleware() {
return [new RateLimited()];
}
}
```### Action Backoff
If you would like to configure how many seconds Laravel should wait before retrying an action that has encountered
an exception on a per-action basis, you may do so by defining a backoff property on your action class:``` php
class BackoffAction
{
use QueueableAction;
/**
* The number of seconds to wait before retrying the action.
*
* @var array|int
*/
public $backoff = 3;
}
```If you require more complex logic for determining the action's backoff time, you may define a backoff method on your action class:
``` php
class BackoffAction
{
use QueueableAction;
/**
* Calculate the number of seconds to wait before retrying the action.
*
*/
public function backoff(): int
{
return 3;
}
}
```You may easily configure "exponential" backoffs by returning an array of backoff values from the backoff method.
In this example, the retry delay will be 1 second for the first retry, 5 seconds for the second retry, and 10 seconds for the third retry:``` php
class BackoffAction
{
/**
* Calculate the number of seconds to wait before retrying the action.
*
*/
public function backoff(): array
{
return [1, 5, 10];
}
}
```### What is the difference between actions and jobs?
In short: constructor injection allows for much more flexibility.
You can read an in-depth explanation here: [https://stitcher.io/blog/laravel-queueable-actions](https://stitcher.io/blog/laravel-queueable-actions#what's-the-difference-with-jobs?!?).### Testing the package
``` bash
composer test
```### Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Contributing
Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
### Security
If you've found a bug regarding security please mail [[email protected]](mailto:[email protected]) instead of using the issue tracker.
## Credits
- [Brent Roose](https://github.com/brendt)
- [Alex Vanderbist](https://github.com/alexvanderbist)
- [Sebastian De Deyne](https://github.com/sebdedeyne)
- [Freek Van der Herten](https://github.com/freekmurze)
- [All Contributors](../../contributors)## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.