tochka-developers / queue-promises
Laravel队列作业的Promise
Requires
- php: 8.1.*|8.2.*|8.3.*
- ext-json: *
- ext-pcntl: *
- bensampo/laravel-enum: ^2.1|^3.0|^4.0|^5.0|^6.0
- laravel/framework: ^v8.37|^9.0|^10.0
- nesbot/carbon: ^2.0|^3.0
Requires (Dev)
- laravel/pint: ^1.16
- mockery/mockery: ^1.6
- orchestra/testbench: ^6.13|^7.1|^8.0
- phpunit/phpunit: ^9.5
- roave/security-advisories: dev-latest
- vimeo/psalm: ^5.25
- dev-master
- v1.4.0
- v1.3.7
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- v1.0.0-rc17
- v1.0.0-rc16
- v1.0.0-rc15
- v1.0.0-rc14
- v1.0.0-rc13
- v1.0.0-rc12
- v1.0.0-rc11
- v1.0.0-rc10
- v1.0.0-rc9
- v1.0.0-rc8
- v1.0.0-rc7
- v1.0.0-rc6
- v1.0.0-rc5
- v1.0.0-rc4
- v1.0.0-rc3
- v1.0.0-rc2
- v1.0.0-rc1
- v1.0.0-beta21
- v1.0.0-beta20
- v1.0.0-beta19
- v1.0.0-beta18
- v1.0.0-beta17
- v1.0.0-beta16
- v1.0.0-beta15
- v1.0.0-beta14
- v1.0.0-beta13
- v1.0.0-beta12
- v1.0.0-beta11
- v1.0.0-beta10
- v1.0.0-beta9
- v1.0.0-beta8
- v1.0.0-beta7
- v1.0.0-beta6
- v1.0.0-beta5
- v1.0.0-beta4
- v1.0.0-beta3
- v1.0.0-beta2
- v1.0.0-beta1
- v0.6.0
- v0.5.0
- v0.4.5
- v0.4.4-beta
- v0.4.3-beta
- v0.4.2-beta
- v0.4.1-beta
- v0.4.0-beta
- v0.3.1
- v0.3.0
- v0.2.8
- v0.2.7
- v0.2.6
- v0.2.5
- v0.2.4
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.12
- v0.1.11
- v0.1.10
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-fix-display-name
- dev-20210217-timeouts
- dev-20200929-bugfix+promisedEvents
- dev-new-promises
- dev-release-job-fix
- dev-lararvel-5.8
- dev-20190613-heartbeat-v2
- dev-20190611_heartbeat
- dev-20190611-bugfix-for-0.4.0-beta
- dev-version-0.3
- dev-carbon-update
This package is auto-updated.
Last update: 2024-09-15 09:28:39 UTC
README
该模块允许链式调用Laravel作业。Promise将在所有链式作业完成后执行(无论成功或失败)。Promise可以访问作业结果。
安装
- 使用
composer
安装此软件包
composer require tochka-developers/queue-promises
- (Laravel 5.4)在
config/app.php
中注册ServiceProvider
'providers' => [ ... \Tochka\Queue\Promises\QueuePromisesServiceProvider::class ... ]
- 发布配置
php artisan vendor:publish --provider="Tochka\Queue\Promises\QueuePromisesServiceProvider"
-
在
config/promises.php
中配置Promise存储。 -
创建Promise存储表
php artisan migrate
用法
创建Promise
所有Promise都从Tochka\Queue\Promises\Jobs\Promise
派生。您可以使用artisan
创建一个模板Promise
php artisan make:promise TestPromise
类详情
Promise类相当简单,因为它只需要两个方法:success
和errors
。当所有链式作业成功完成时,由提供者调用success
。当任何作业失败时,调用errors
。
<?php namespace App\Promises; use Tochka\Queue\Promises\Jobs\Promise; class TestPromise extends Promise { /** * Instance initialization * * @return void */ public function __construct() { // Jobs chaining may be done here } /** * This will be called after all jobs of the promise have finished execution, but before success or errors. * If this method returns false, success and errors won't be called. * * @return bool */ public function before(): bool { // ... return true; } /** * This will be called if all the jobs have completed successfully. * * @return bool */ public function success(): bool { // ... return true; } /** * This will be called if one or more jobs have failed. * * @return bool */ public function errors(): bool { // ... return true; } /** * This will be called if the promise timed out. * * @return bool */ public function timeout(): bool { // ... return true; } /** * This will be called after the execution of success or errors * * @return bool */ public function after() { // ... return true; } }
上述任何方法都可能没有实现。如果方法缺失,则假定它执行无操作并返回true
。
链初始化
为了使作业可以附加到Promise,它们必须实现Tochka\Queue\Promises\Contracts\MayPromised
接口。最常见的使用案例收集在Tochka\Queue\Promises\Jobs\Promised
特质中。您可以将这些特质简单地附加到您的类中,如下所示
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Tochka\Queue\Promises\Contracts\MayPromised; use Tochka\Queue\Promises\Jobs\Promised; class SomeJob implements ShouldQueue, MayPromised { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Promised; public $text; public function __construct($text) { $this->text = $text; } public function handle() { // some actions } }
通过将任何数量的作业添加到Promise来构建链
$promise = new TestPromise(); $promise->add(new SomeJob('job 1')) ->add(new SomeJob('job 2')) ->add(new SomeJob('job 3')) ->add(new SomeJob('job 4'));
之后,Promise可以以两种模式之一运行
$promise->runSync(); // Run the promise synchronously $promise->runAsync(); // Run the promise asynchronously
- 在同步模式下,所有链式作业将按顺序依次运行,直到其中之一失败或全部成功完成。之后,将执行Promise的
success
或errors
。 - 在异步模式下,所有作业将立即入队,Promise将等待它们完成。
可以通过方法调用精细配置终止条件
$promise->setPromiseFinishConditions( true, // The promise must execute when a job completes successfully for the first time. true // The promise must execute when a job fails for the first time. );
为了方便,runSync
和runAsync
也可以接受相同的参数。
等待事件
有时需要在一个事件被分发后执行Promise,而不仅仅是当一定数量的作业完成。等待事件是通过Tochka\Queue\Promises\Jobs\WaitEvent
作业完成的
$promise = new TestPromise(); $promise->add(new WaitEvent(SomeEvent1::class, 100)) ->add(new WaitEvent(SomeEvent2::class, 100)); $promise->run()
WaitEvent
的构造函数接收一个等待的事件的类和一个唯一标识符(未指定类型)。如果没有提供标识符,则WaitEvent
将等待期望类的任何事件。如果给构造函数提供了标识符,则WaitEvent
将只在具有此标识符的事件被分发时完成。为了使其正常工作,该事件必须实现Tochka\Queue\Promises\Contracts\PromisedEvent
接口
class SomeEvent implements PromisedEvent { public $id; public $data; public function __construct($id, string $data) { $this->id = $id; $this->data = $data; } /** * Get the event id * @return string */ public function getUniqueId() { return $this->id; } }
getUniqueId
必须返回一个标识符或null
,如果没有标识符存在。
请注意,如果等待一个不实现该接口的类,则WaitEvent
永远不会完成。
Promise超时
有时,如果某些链式作业尚未完成,则在超时事件后执行Promise可能很有用。这是通过特殊的延迟检查作业实现的。
您必须配置超时子系统
- 将配置参数
timeout_queue
设置为包含检查作业将被发布的队列的名称。默认情况下,检查作业被发布到default
队列。 - 为超时队列运行监听器或将其添加到现有监听器的队列列表中。
之后,承诺可能被设置为过期。设置超时的两种方法可行
setTimeout($timeout)
— 承诺将在给定时间(以秒为单位)执行,或在所有工作完成之后(以先到者为准)。setExpiredAt(Carbon $expired_at)
— 承诺将在给定的戳记(更准确或更不准确)执行,或在所有工作完成之后(以先到者为准)。
如果承诺超时,则调用timeout
方法(如果已定义)。
处理结果
getResults
方法返回所有链式作业的结果
public function before(): bool { $results = $this->getResults(); foreach ($results as $result) { $status = $result->getJobStatus(); // This returns the job execution status } }
作业结果以实现Tochka\Queue\Promises\Contracts\MayPromised
的类返回。
依赖注入
获取作业结果的另一种方法是通用方法before
、success
、errors
、timeout
和after
的依赖注入版本。
public function errors(SomeJob1 $job1, SomeJob2 $job2): bool { echo $job1->getJobStatus(); echo $job2->getJobStatus(); }
DI的工作方式如下
- 如果参数实现了
Tochka\Queue\Promises\Contracts\MayPromised
的类型,则相应的结果将被注入到该参数中; - 如果参数实现了
Tochka\Queue\Promises\Contracts\PromisedEvent
(这在承诺等待事件时很有用),则事件本身将作为该参数传递; - 如果存在多个所需类的结果,则只有第一个将被绑定;
- 如果有多个相同类的参数(例如,如果承诺等待同一类的多个作业),则结果的顺序对应于链中作业的顺序
$promise->add(new SomeJob('job 1')) ->add(new SomeJob('job 2')) ->add(new SomeJob('job 3')) ->add(new SomeJob('job 4')); //... public function errors(SomeJob $job1, SomeJob $job2, SomeJob $job3, SomeJob $job4): bool { echo $job1->text; // job 1 echo $job2->text; // job 2 echo $job3->text; // job 3 echo $job4->text; // job 4 }
请注意,如果承诺异步运行,则无法保证作业执行的顺序。这可能会产生不希望的结果
public function errors(SomeJob $job1, SomeJob $job2, SomeJob $job3, SomeJob $job4): bool { echo $job1->text; // job 3 echo $job2->text; // job 1 echo $job3->text; // job 2 echo $job4->text; // job 4 }
- 如果没有适合参数的结果,则传递
null
; - 如果参数类型没有实现
Tochka\Queue\Promises\Contracts\MayPromised
,则将通过Laravel DI构建传递给它的值(类似于调用app()
并传递类名时的结果)。
Tochka\Queue\Promises\Contracts\MayPromised
接口声明以下方法
/** * Get the job execution status * Returns either MayPromised::JOB_STATUS_SUCCESS or MayPromised::JOB_STATUS_ERROR * @return string */ public function getJobStatus(): string; /** * Get the job execution errors * Returns an array ['code' => ..., 'message' => ...] * @return array */ public function getJobErrors(): array;