teamzac/laravel-workflows

一个用于运行队列化、多步骤工作流的Laravel包

v0.2.1 2022-07-27 17:29 UTC

This package is auto-updated.

Last update: 2024-09-22 19:15:22 UTC


README

Latest Version on Packagist Total Downloads

Laravel应用中,管道是一个强大的工具,但有时您需要执行可能分为多个步骤的长时间运行的任务,并且在出现错误并需要从当前点重新启动的情况下,有更好的支持。此包有助于这些类型的工作流。

此包可供公共使用,但请注意,它目前是为我们的特定用例构建的。它已从旧应用中提取出来并更新了一点点,以适应更广泛的使用。可能存在一些我们没有考虑到的情况,并且可能还有一些尚未包含的明显功能。它可能不符合您的所有需求。如果您想为此做出贡献,那将非常棒!但如果您需要的功能与包的使用不匹配,请在之前与我们联系。

安装

您可以通过composer安装此包

composer require teamzac/laravel-workflows

此包使用自动发现,因此您不需要将其包含在您的 config/app.php 文件中。

您可以发布配置并调整设置,包括工作流实例表的名称。

php artisan vendor:publish --provider="TeamZac\Workflow\WorkflowServiceProvider"

一旦准备好,迁移数据库以创建 workflow_instances 表。您也可以发布迁移文件,如果您希望修改它。您可以在配置中更改表名。

php artisan migrate

概念

工作流

工作流 由一个或多个 工作流步骤 组成。当您运行工作流时,此包将迭代每个工作流步骤。如果遇到未处理的错误,工作流将被暂停;否则,它将继续到下一个步骤,直到没有更多步骤。

工作流步骤

工作流步骤 是工作流中需要处理的潜在多个任务之一。

工作流实例

工作流实例 是工作流的具体实例,通常包括工作流将执行操作的特定数据。在此包中,工作流实例通过Eloquent模型表示,并存储在您的数据库中。

工作流管理器

这是您应用程序中工作流的中央存储库。您应该在服务提供器中注册您的工作流。它提供了方便的访问来运行和管理工作流。

用法

创建工作流

在您运行工作流之前,您需要创建一个。您可以在任何您想的地方创建一个新的 TeamZac\Workflows\AbstractWorkflow 子类。您还可以使用内置的生成器来快速生成新的工作流

// example
php artisan make:workflow App\\Workflows\\TestWorkflow

抽象工作流子类为您做了很多工作,所以您只需要定义应该执行的工作流步骤

<?php

namespace App\Workflows;

use TeamZac\Workflows\AbstractWorkflow;

class TestWorkflow extends AbstractWorkflow
{
  protected $steps = [
      'App\Workflows\StepOne',
      'App\Workflows\StepTwo',
      'App\Workflows\StepThree',
    ];
}

您可以自由组织您的代码。这只是一个示例。

每个工作流步骤应该是 TeamZac\Workflows\AbstractWorkflowStep 的子类。手动创建所有这些类将是一件痛苦的事情,因此此包提供了一个方便的生成器。

注册新的工作流

在您可以使用它之前,请确保使用工作流管理器注册您的流程。如果您愿意,可以在服务提供器的 boot() 方法中这样做

namespace App\Providers;

use TeamZac\Workflow\Facades\Workflow;

class AppServiceProvider 
{
  public function boot() 
    {
    Workflow::extend('test-workflow', function() {
          return new \App\Workflows\TestWorkflow;
        });
  }
}

工作流管理器使用Laravel的内置管理器模式。只需使用键和返回工作流的回调调用 extend() 方法即可。您可以在这里进行任何可能需要的设置。

生成工作流步骤类

现在您已经注册了工作流,您可以使用生成器

php artisan workflow:generate test-workflow

这将检查 $steps 变量并创建类似 php artisan event:generate 的工作流步骤类。

创建 WorkflowInstance

工作流依赖于 WorkflowInstance,该实例被传递到每个 WorkflowStep 中。它是一个典型的 Eloquent 模型,因此您可以像通常那样创建它。

$instance = TeamZac\Workflows\WorkflowInstance::create([
  'workflow' => 'test-workflow',
]);

必需的字段是 workflow 键,它应引用您注册 Workflow 时使用的键。

可工作流关系

WorkflowInstances 可以通过多态关系 workflowable 引用您域中的任何 Eloquent 对象。例如,如果您正在对用户运行 Workflow,这将允许您直接访问该对象。

元数据

您还可以使用 WorkflowInstance 的 metadata 属性存储任意的键/值数据。该字段被转换为一个数组。

运行工作流

一旦您有了 WorkflowInstance,您可以通过两种方式运行它

// by calling run() directly on the instance
$instance->run();

// by passing it through the Workflow facade
Workflow::run($instance);

// by manually creating an instance of the Workflow driver, setting the instance, and calling run
Workflow::driver('test-workflow')->setInstance($instance)->run();

最后一种方式是幕后进行的,实际上没有理由自己这样做,但如果您愿意,请随意。

一旦调用 $instance->run();,将派发 TeamZac\Workflows\RunWorkflowStepJob。您可以配置要使用的队列。

RunWorkflowStepJob 接收 Workflow(以及之前设置的实例)和下一个要运行的步骤。

以下是过程

  1. 如果此实例是在 Workflow 的开始处启动的,将触发开始事件
  2. 实例的状态将更新为 "in_progress"(进行中)
  3. 将通过调用容器中的 handle() 方法来运行下一个 WorkflowStep
  4. 如果抛出了未处理的异常,实例将被暂停,并派发任何暂停的事件。
  5. 如果没有抛出未处理的异常,我们将检查是否有其他步骤。
  6. 如果有下一个步骤,它将被排队并运行(回到步骤 3)。
  7. 否则,实例将被标记为完成,并触发完成事件。

与 WorkflowSteps 一起工作

如果您在 WorkflowStep 上定义了一个 protected $statusMessage 属性,当步骤成功完成后,WorkflowInstance 将使用该消息进行更新

  protected $statusMessage = 'Multiplied by 2';
    
    ...
    
    // after completing this step:
    echo $instance->status_message;
    // echoes "Multiplied by 2"

如果您需要执行一些逻辑来决定状态消息,可以覆盖 getStatusMessage() 而不是直接设置该属性。

  public function getStatusMessage()
    {
      // some logic here
        return 'message';
    }

如果您需要在步骤完成前后执行一些操作,可以使用 WorkflowStep 类上的 setup()tearDown() 方法。

您的工作流步骤的实质应位于 handle() 方法中,该方法在容器外调用,因此可以使用依赖注入。

您可以使用 WorkflowStep 上的 getInstance() 方法访问 WorkflowInstance。

您可以直接通过 getMetadata() 方法访问实例的元数据。传递一个键以检索特定的值,或传递 null 以获取整个元数据数组。

事件

以下事件默认派发

TeamZac\Workflows\Events\WorkflowStarted 当 WorkflowInstance 开始运行其第一个步骤时。

TeamZac\Workflows\Events\WorkflowStepCompleted 当 WorkflowStep 已成功完成时。

TeamZac\Workflows\Events\WorkflowPaused 当未处理的异常导致 Workflow 暂停时。您将收到 WorkflowInstance 以及原始异常,这样您就可以向错误跟踪系统报告或执行您想做的事情。

TeamZac\Workflows\Events\WorkflowCompleted 当最后一个 WorkflowStep 已成功完成时。

您可以根据需要自定义要派发的事件,或者简单地将这些事件引用到您的 EventServiceProvider 中。

测试您的工作流步骤

您可以在测试套件中运行工作流,但如果您想测试单个步骤而无需运行所有前面的步骤,可以使用 Workflow Manager 上的 test() 方法。

Workflow::test($workflowInstance, StepClass::class);

这将构建工作流步骤,设置实例,并触发它。它不会返回任何内容(尽管我们可能在未来添加一些测试辅助工具)。然而,您可以针对在运行工作流步骤期间应该更改的任何数据进行测试。

配置

您可以发布配置文件

php artisan vendor:publish --provider=TeamZac\\Workflows\\WorkflowServiceProvider --tag=config

您也可以选择发布迁移

php artisan vendor:publish --provider=TeamZac\\Workflows\\WorkflowServiceProvider --tag=migrations

然而,您可以在配置中自定义WorkflowInstance的表名,所以如果您不需要添加或更改任何表列,除非您只是想拥有它,否则实际上没有发布迁移的必要。

配置选项

一旦发布,您可以通过config/workflows.php访问配置。

instance_table 允许您定义用于存储WorkflowInstance的表的名称。

instance_model 允许您使用自己的TeamZac\Workflow\WorkflowInstance子类。

timeout 为队列中的工作设置自定义超时。

queue 允许您定义要使用哪个队列。默认设置为'default',但您可能希望将工作流程步骤移动到单独的队列。

events 允许您选择在工作流程生命周期中的不同点广播哪些事件。您可以使用自己的与我们的结合使用,或完全删除我们的。只需确保您的构造函数正确接收与内置事件相同的参数。

待办事项

  • 添加一个命令来清除旧的流程实例
  • 一些代码有点杂乱,我会在有机会的时候清理它们

测试

composer test

更新日志

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

贡献

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

安全

如果您发现任何与安全相关的问题,请通过电子邮件chad@zactax.com联系,而不是使用问题跟踪器。

鸣谢

许可证

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