Позволяет создавать цепочки задач в рамках очередей Laravel, после завершения работы которых будет выполнена определенная задача (промис). Промис выполнится несмотря на результат работы задач в цепочке, в нем можно настроить различное поведение исходя из результатов.
- Выполняем команду:
composer require tochka-developers/queue-promises- Опубликуйте конфигурацию:
php artisan vendor:publish --tag=promises-config-
В файле
config/promises.phpможно указать настройки подключения к БД, а также таблицы для хранения промежуточных данных. -
Создайте миграции на необходимые таблицы:
php artisan promise:make-migration...
Пакет оперирует следующими понятиями:
- промис, обработчик промиса - класс, который отвечает за обработку результатов конкретной цепочки заданий.
- задание - любой класс-обработчик, выполняющий некую работу асихронно (Job с интерфейсом ShouldQueue, специальный обработчик ожидания события WaitEvent, другой промис)
Для быстрого запуска нам нужен сам класс промиса. Он должен реализовывать интерфейс
Tochka\Promises\Contracts\PromiseHandler. Для удобства все объявленные в интерфейсе методы уже реализованы в
трейте Tochka\Promises\Support\DefaultPromise.
Пример класса:
<?php
namespace App\Promises;
use App\Jobs\ExampleJob;
use Tochka\Promises\Contracts\PromiseHandler;
use Tochka\Promises\Support\DefaultPromise;
use Tochka\Promises\Support\Sync;
class ExamplePromise implements PromiseHandler
{
use DefaultPromise;
use Sync;
private int $foo;
public function __construct(int $foo)
{
$this->foo = $foo;
}
public function handle(ExampleJob $job): void
{
$result = $this->foo + $job->getMyJobResult();
// действия
}
}Пример создания и запуска цепочки заданий:
$promise = new ExamplePromise(123);
$promise->add(new ExampleJob($initialValue));
$promise->add(new AnotherJob($initialValue));
$promise->run();Каждое задание, добавляемое в цепочку, должно реализовывать интерфейс Tochka\Promises\Contracts\MayPromised.
Для удобства рекомендуется подключить трейт Tochka\Promises\Support\PromisedJob, в котором все необходимые методы уже
реализованы.
В указанном примере после вызова метода run у промиса произойдет следующее:
- указанный промис и добавленные в него задания будут сохранены в БД
- в очередь Laravel добавится первое указанное задание (
ExampleJob) - после того, как задание будет обработано, в очередь добавится второе задание (
AnotherJob) - после того, как второе задание будет обработано - в очередь добавится сам промис(
ExamplePromise), который выполнит необходимые действия с результатами работы заданий
...
Основные сущности пакета (промис и задания) - по сути простые StateMachine. Т.е. каждое задание, и сам промис хранит информацию о текущем состоянии и условиях перехода от одного состояния к другому.
Список состояний:
waiting- ожидание. Означает, что в данный момент задание или промис не выполняются и ждут выполнения других условий для своего запускаrunning- запущено. Для задания это означает, что задание помещено в очередь Laravel и ожидает его выполнения. Для промиса это означает, что в текущий момент цепочка заданий этого промиса находится на этапе выполненияsuccess- успешное завершение. Означает, что задание или промис успешно завершили работу.failed- завершение с ошибкой. Для задания означает, что оно не смогло выполниться корректно/завершилось с ошибками. Для промиса это означает, что какие-то из заданий в цепочке завершились с ошибкой.timeout- завершено по истечению времени. Означает, что задание или сам промис не успели завершиться в указанный промежуток времени, а потому были завершены досрочно.canceled- отменено. Означает, что задание было отменено еще до этапа выполнения (а значит, фактически не выполнялось)
Все состояния указаны в классе Tochka\Promises\Enums\StateEnum. Все внутренние структуры пакета работают с состояниями
через этот enum. В дальнейшем в документации мы будем опускать этот факт, указывая просто название состояния, но следует
иметь в виду, что строка передайте в метод состояние success на самом деле означает передайте в метод экземпляр класса StateEnum со значением success (StateEnum::SUCCESS()).
Условия перехода между состояниями - это набор экземпляров класса Tochka\Promises\Core\Support\ConditionTransition,
в котором хранятся следующие значения:
- condition - условия перехода. Экземпляр интерфейса
Tochka\Promises\Contracts\ConditionContract. По сути это класс с одним методов condition, который должен вернуть значениеtrueилиfalse - from_state - начальное состояние, для которого корректно условие перехода.
- to_state - конечное состояние, к которому нужно привести сущность при выполнении условия condition.
В простом виде переход между состояниями промиса и задания выглядит так:
- фильтруются все
ConditionTransitionпо полюfrom_state, исходя из текущего состояния (т.е. для задания в состоянииrunningбудут отобраны переходы со значениемrunningв поле from_state) - у всех переходов проверяются условия перехода (вызывается метод
conditionу объектаConditionContract) - если условия перехода для какого-то из переходов истинно - то сущности назначается новое состояние
to_state
Класс промиса должен реализовывать интерфейс Tochka\Promises\Contracts\PromiseHandler.
...
...
...
Класс промиса необходим для обработки результатов всей цепочки, либо выполнения каких-либо действий после выполнения всех заданий. Для выполнения таких действий вы можете использовать несколько методов-хуков:
-
public function before(): bool - метод выполняется до всех других методов. Если метод возвращает false - все следующие методы не будут вызваны (кроме метода
after) -
public function success(): void - метод вызывается, если состояние промиса -
SUCCESS -
public function failed(): void - метод вызывается, если состояние промиса -
FAILED -
public function timeout(): void - метод вызывается, если состояние промиса -
TIMEOUT -
public function handle(): void - метод вызывается при любом состоянии промиса
-
public function after(): void - метод вызывается после исполнения всех предыдущих методов, игнорируя возвращаемое в методе
beforeзначение
...
...
...
...
...
...
...
...