Skip to content

Latest commit

 

History

History
176 lines (139 loc) · 10.5 KB

File metadata and controls

176 lines (139 loc) · 10.5 KB

Queue Promises

Позволяет создавать цепочки задач в рамках очередей 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), который выполнит необходимые действия с результатами работы заданий

PromiseWatcher

...

Принцип работы

Основные сущности пакета (промис и задания) - по сути простые 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.

Условия смены состояний промиса и заданий

Стандартные условия

Синхронный промис (Sync)

...

Асинхронный промис (ASync)

...

Таймаут (Timeout и ExpiredAt)

...

Обработка результатов

Класс промиса необходим для обработки результатов всей цепочки, либо выполнения каких-либо действий после выполнения всех заданий. Для выполнения таких действий вы можете использовать несколько методов-хуков:

  • 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 значение

Задания

Обычные задания (Job with ShouldQueue)

...

Промисы

...

Ожидание событий (WaitEvent)

...

Кастомные задания (Dispatchers)

...

События

...

GarbageCollector

...

Тестирование

...

Возможные проблемы

...