teamzac / laravel-workflows
一个用于运行队列化、多步骤工作流的Laravel包
Requires
- php: >=7.2.5
- bensampo/laravel-enum: ^3.0|^4.0|^5.0
- illuminate/support: ^8.0|^9.0
Requires (Dev)
- orchestra/testbench: 6.*|7.*
- phpunit/phpunit: ^8.5|^9.0
README
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(以及之前设置的实例)和下一个要运行的步骤。
以下是过程
- 如果此实例是在 Workflow 的开始处启动的,将触发开始事件
- 实例的状态将更新为 "in_progress"(进行中)
- 将通过调用容器中的
handle()
方法来运行下一个 WorkflowStep - 如果抛出了未处理的异常,实例将被暂停,并派发任何暂停的事件。
- 如果没有抛出未处理的异常,我们将检查是否有其他步骤。
- 如果有下一个步骤,它将被排队并运行(回到步骤 3)。
- 否则,实例将被标记为完成,并触发完成事件。
与 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)。有关更多信息,请参阅许可证文件。