eplayment/laravel-queueable-action

Laravel中的队列支持动作

dev-main 2024-02-15 07:10 UTC

This package is not auto-updated.

Last update: 2024-09-27 08:06:05 UTC


README

Latest Version on Packagist GitHub Workflow Status Check & fix styling Total Downloads

动作是结构化Laravel业务逻辑的一种方式。此包添加了对它们进行队列化的简单支持。

$myAction->onQueue()->execute();

您可以指定一个队列名称。

$myAction->onQueue('my-favorite-queue')->execute();

支持我们

我们投入了大量资源来创建一流的开放式源代码包。您可以通过购买我们的付费产品之一来支持我们。

我们非常感谢您从您的家乡寄来明信片,说明您正在使用我们的哪些包。您可以在我们的联系页面上找到我们的地址。我们将所有收到的明信片发布在我们的虚拟明信片墙上

安装

您可以通过composer安装此包。

composer require spatie/laravel-queueable-action

您可以选择通过以下方式发布配置文件:

php artisan vendor:publish --provider="Spatie\QueueableAction\QueueableActionServiceProvider" --tag="config"

这是已发布配置文件的内容

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,
];

使用方法

如果您想了解动作及其异步使用的背后的原因,您应该阅读专门的博客文章:https://stitcher.io/blog/laravel-queueable-actions

您可以使用以下Artisan命令动态生成队列化和同步动作类。

php artisan make:action MyAction [--sync]

以下是一个使用队列化动作的示例

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.
    }
}
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);
    }
}

该包还支持使用__invoke()方法进行动作。这将被自动检测。以下是一个示例

class MyInvokeableAction
{
    use QueueableAction;

    public function __invoke(
        MyModel $model,
        RequestData $requestData
    ) {
        // The business logic goes here, this can be executed in an async job.
    }
}

使用__invoke()方法的动作应该像上述示例中解释的那样添加到队列中,即在onQueue()方法之后运行execute()方法。

$myInvokeableAction->onQueue()->execute($model, $requestData);

测试队列化动作

该包在Spatie\QueueableAction\Testing\QueueableActionFake类中提供了一些测试断言。您可以在PhpUnit测试中使用它们,如下所示

/** @test */
public function it_queues_an_action()
{
    Queue::fake();

    (new DoSomethingAction)->onQueue()->execute();

    QueueableActionFake::assertPushed(DoSomethingAction::class);
}

在使用QueueableActionFake断言之前,不要忘记使用Queue::fake()来模拟Laravel的队列。

以下断言可用

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)

如果您觉得任何其他的QueueFake断言缺失,请随时发送PR。

链式动作

您可以通过将它们包装在ActionJob中来链式调用动作。

以下是一个具有相同参数的两个动作的示例

use Spatie\QueueableAction\ActionJob;

$args = [$userId, $data];

app(MyAction::class)
    ->onQueue()
    ->execute(...$args)
    ->chain([
        new ActionJob(AnotherAction::class, $args),
    ]);

ActionJob将动作类实例作为第一个参数,后面跟着动作的参数数组。

自定义标签

如果您想更改在Horizon中显示的自定义动作的标签,可以覆盖tags()函数。

class CustomTagsAction
{
    use QueueableAction;

    // ...

    public function tags() {
        return ['action', 'custom_tags'];
    }
}

作业中间件

可以通过覆盖middleware()函数来添加通过动作作业传递的中间件。

class CustomTagsAction
{
    use QueueableAction;

    // ...

    public function middleware() {
        return [new RateLimited()];
    }
}

动作回退

如果您想为每个动作配置Laravel在遇到异常时应该等待多少秒后重试动作,您可以在动作类上定义一个回退属性来这样做

class BackoffAction
{
    use QueueableAction;
    
    /**
     * The number of seconds to wait before retrying the action.
     *
     * @var array<int>|int
     */
    public $backoff = 3;
}

如果您需要更复杂的逻辑来确定动作的回退时间,您可以在动作类上定义一个回退方法

class BackoffAction
{
    use QueueableAction;
    
    /**
     * Calculate the number of seconds to wait before retrying the action.
     *
     */
    public function backoff(): int
    {
        return 3;
    }
}

您可以通过从回退方法返回一个回退值数组来轻松配置“指数”回退。在这个例子中,第一次重试的延迟将是1秒,第二次重试是5秒,第三次重试是10秒。

class BackoffAction
{
    /**
     * Calculate the number of seconds to wait before retrying the action.
     *
     */
    public function backoff(): array
    {
        return [1, 5, 10];
    }
}

动作和作业有什么区别?

简而言之:构造函数注入提供了更大的灵活性。您可以在这里阅读深入的解释:https://stitcher.io/blog/laravel-queueable-actions

测试软件包

composer test

变更日志

有关最近更改的更多信息,请参阅变更日志

贡献

有关详细信息,请参阅贡献指南

安全性

如果您发现有关安全性的错误,请通过security@spatie.be发送邮件,而不是使用问题跟踪器。

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件