# Очередь сценариев

## 1. Введение

Когда один сценарий запускается несколько раз за короткий промежуток времени возникает нагрузка на сервисы API и базу данных Бипиума. Если сценарий совершает много операций с данными, повышенная нагрузка приведет к серверной ошибке из-за большого числа запросов к API (429, Too Many Requests). Чтобы избежать этого, используйте очередь сценариев.

Очередь сценариев позволяет:

* **Последовательно запускать одинаковые сценарии**\
  Следующий сценарий не начнет выполнение пока предыдущий не завершит работу.
* **Параллельно запускать разные сценарии**\
  Разные сценарии будут запущены независимо друг от друга.
* **Повторно запускать сценарии завершенные с ошибкой**\
  Если сценарий завершился с ошибкой, очередь попытается выполнить его еще раз. Например, когда сценарий обращается к внешнему сервису который на данный момент недоступен.

## 2. Принцип работы

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FpVFDF0b3TK8MQUtpQS5L%2Ftemp%20-%20Frame%2012\(2\).jpg?alt=media\&token=0c21f3be-349f-46d9-8f90-886e218be3c9)

* В каталоге «Очередь» фиксируются записи со сценариями и их входными данными.
* Сценарий обработки очереди реагирует на добавление записи в каталог: запускает указанный в записи сценарий с его параметрами запуска.
* При успешном завершении сценарий фиксирует это статусом и больше не попадает в очередь.
* При завершении с ошибкой, сценарий очереди запустит его повторно. Количество попыток можно задать параметром в сценарии обработки очереди.

## **3. Реализация**

### **3.1. Каталог для хранения сценариев в очереди**

Создайте каталог «Очередь». При создании каталога нужно добавить и настроить поля следующим образом. Создавать поля нужно в том же порядке, не нарушая последовательности их id.

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FykK2grkaYuK5OI3AzQ8d%2F%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C1.png?alt=media\&token=85e0a7ff-072d-454d-860d-a036de1b3f2e)

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FMwYBW1cGRvpYALbExdJY%2F%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C2.png?alt=media\&token=dedd4247-2298-449b-9713-62a7b826936b)

* **Выполнить** (Секция)
* **Сценарий** (связанный каталог)\
  Описание: Сценарий, который будет выполнен.\
  Связанный каталог: Сценарии.\
  Настройки: Обязательное поле.
* **Параметры запуска** (Текст)\
  Описание: Свойства и их значения, к которым может обращаться запущенный сценарий.\
  Формат вводимых данных: JSON-объект.\
  Настройки: Многострочный текст, обязательное поле.
* **Исполнение** (Секция)
* **Статус** (Статус)\
  Описание: Текущее состояние сценария.\
  Значения: Запланировано, Исполнение, Готово, Ошибка.\
  Настройки: Обязательное поле, по умолчанию: первый элемент.
* **Код процесса** (Текст)\
  Описание: Код запущенного экземпляра сценария.\
  Настройки: Текст.
* **Дата запуска** (Дата)\
  Описание: Дата последнего запуска сценария.\
  Настройки: Дата со временем.
* **Дата завершения** (Дата)\
  Описание: Дата последнего завершения сценария (с ошибкой или успешно).\
  Настройки: Дата со временем.
* **Кол-во запусков** (Число)\
  Описание: Количество запусков сценария.\
  Настройки: Минимальное значение — 0.
* **Ошибки** (Текст)\
  Описание: Описание ошибки сценария.\
  Настройки: Многострочный текст.
* **Служебная информация** (Секция)
* **Создано** (Дата)\
  Описание: Дата создания записи.\
  Настройки: Со временем, по умолчанию: текущее время, редактируемое только через API.

Пример заполненной карточки в каталоге «**Очередь**»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FyNiDdTOV5W8Xfmm3rzMS%2F%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png?alt=media\&token=33cdab76-7f2c-4ec3-b632-065db558c542)

### **3.2. Событие для запуска сценария обработки очереди**

В каталоге «События» создайте новую запись и заполните ее следующим образом:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FuON435F9WIB79rvivZWq%2F%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D0%B5_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png?alt=media\&token=4fdfdce9-1c33-497e-b6c6-28785ca92cfa)

В качестве сценария загрузите [сценарий обработки очереди](https://drive.google.com/file/d/1VPwKsN5-9o8WxxjOV7_neEg2e8OCQNc6/view?usp=sharing).

### **3.3. Сценарий обработки очереди**

Сценарий обработки очереди выглядит следующим образом:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FQPJfFf36KZv3PiIxnluv%2F%D1%81%D1%86%D0%B5%D0%BD%D0%B0%D1%80%D0%B8%D0%B9_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png?alt=media\&token=4d68cf05-f3fc-4af4-8f7c-baec6e1977c5)

В зависимости от типа события, происходит следующее:

* Если тип события «Уведомление о создании записи», сценарий задает количество запусков как 0. Далее сценарий проверяет есть ли другие записи в очереди с тем же сценарием, которые должны выполниться раньше. Если таких сценариев нет – запускает в работу сценарий из созданной записи.
* Если тип события «Уведомление об изменении записи», то логика следующая:\
  \
  Если сценарий в измененной записи завершился с ошибкой, сценарий очереди запускает его еще раз. Максимальное число повторных запусков - 5.\
  Если сценарий в измененной записи завершился успешно - сценарий очереди берет из очереди следующую запись и запускает сценарий в ней.

{% hint style="warning" %}
Сценарий обработки очереди работает по статусам записей в очереди, но не проставляет их. Для корректной работы очереди вам нужно изменить статус записи очереди самостоятельно, из запускаемого в записи очереди сценария. Для этого в каждый запускаемый очередью сценарий передаются следующие параметры запуска:

* queueRecordId — id записи в каталоге «Очередь», из которой вызывается сценарий.
* queueStartCount — Число запусков сценария в этой записи очереди.
* payload — произвольные входные данные для сценария в формате JSON. Передаются из поля «Параметры запуска» этой записи очереди.
  {% endhint %}

Ко всем описанным выше параметрам запуска есть доступ из вызванного очередью сценария.

### **3.4. Сценарий в записи очереди**

Сценарий в записи очереди может быть любым. Единственное ограничение - необходимость простановки из него статуса и числа запусков в запись очереди, из которой он был запущен.

Запись очереди необходимо изменять:

* В начале работы сценария (после компонента «Начало процесса»). Необходимо проставить статус «Исполняется» и увеличить число запусков на 1 в записи очереди. Здесь же можно проставить «Дату запуска» и «Код процесса», но эти поля не обязательны.
* В конце работы сценария (перед компонентом «Конец процесса»). Необходимо проставить статус «Готово». Здесь же можно проставить «Дату завершения».
* Во всех компонентах, в которых возможно возникновение ошибки. В качестве неудачной ветки можно использовать выход из компоненты по [ошибке](https://docs.bpium.ru/manual/processes/scripts/components/error) или же прописать собственную логику, приводящую к ошибке. Необходимо проставить статус «Ошибка» и увеличить количество запусков на 1 в записи очереди.

Пример простого сценария, обращающегося к стороннему сервису в записи очереди:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FyH4vV1qPgKTjIKzAEqcE%2F%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%BE%D0%B9_%D1%81%D1%86%D0%B5%D0%BD%D0%B0%D1%80%D0%B8%D0%B9_%D0%B2_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png?alt=media\&token=471b6b45-9266-4e7a-afa7-695bfd21a9f3)

Пример заполнения компонентов, назначающих статусы исполнения в запись очереди:

* Компонент «Статус **—** исполняется»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2F8W8tbQy8X4bEEgxLmEIJ%2F%D1%81%D1%82%D0%B0%D1%82%D1%83%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D0%BD%D1%8F%D0%B5%D1%82%D1%81%D1%8F.png?alt=media\&token=10282bcb-3f77-47cd-adb8-58a755128163)

* Компонент «Выкидываем ошибку»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FWmNwOuxGO8juCZZ54QAM%2F%D0%B2%D1%8B%D0%BA%D0%B8%D0%B4%D1%8B%D0%B2%D0%B0%D0%B5%D0%BC_%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D1%83.png?alt=media\&token=c71d0e18-56fc-488e-af3d-b3c719c64616)

* Компонент «Статус — завершен»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FW8suuD4DRxVZBi97u6cb%2F%D1%81%D1%82%D0%B0%D1%82%D1%83%D1%81_%D0%B7%D0%B0%D0%B2%D0%B5%D1%80%D1%88%D0%B5%D0%BD.png?alt=media\&token=a75ba9de-be21-4026-8559-61201621e683)

## **4. Тестирование**

### **4.1. Создание тестового сценария**

В каталоге «Сценарии» создайте тестовый сценарий для проверки очереди. Для большей наглядности используйте компонент «[Таймер](https://docs.bpium.ru/manual/processes/scripts/components/timer)», чтобы увеличить время работы сценария. Пример сценария:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FqMfMhD0M0PAbhlJL3vSc%2F%D1%82%D0%B5%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9_%D1%81%D1%86%D0%B5%D0%BD%D0%B0%D1%80%D0%B8%D0%B9.png?alt=media\&token=97ef7e0c-1328-4848-9b4e-d4e03d9606d9)

Компоненты «Статус **—** исполняется» и «Статус — завершен» заполните согласно скриншотам выше.

### **4.2. Создание записей в Очереди**

В каталоге «Очередь» создайте запись с созданным ранее тестовым сценарием. В качестве входных данных укажите произвольный JSON, например - {}. Пример заполнения:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FyNiDdTOV5W8Xfmm3rzMS%2F%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C_%D0%BE%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D0%B8.png?alt=media\&token=33cdab76-7f2c-4ec3-b632-065db558c542)

После создания записи ее статус перейдет в состояние «Исполнение»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FGbLRxX5VMWj5QsLEyfN0%2F%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D0%BD%D1%8F%D0%B5%D1%82%D1%81%D1%8F.png?alt=media\&token=29b529ad-4bda-449f-965c-b9171281de6b)

Во время исполнения сценария создайте еще одну запись в каталоге «Очередь» с тем же сценарием. Созданная запись останется в статусе «Запланировано»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2F46F3RNCpWHpP3CObMT1e%2F%D0%B6%D0%B4%D0%B5%D1%82.png?alt=media\&token=56faaae4-9f7f-4fdb-addb-bc3cfa7cadab)

Дождитесь окончания выполнения сценария в первой записи очереди. После окончания выполнения сценария, статус в первой записи очереди изменится на «Готово»:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2FySSrcCyz3Pe9r5zlK45C%2F%D0%B7%D0%B0%D0%B2%D0%B5%D1%80%D1%88%D0%B5%D0%BD.png?alt=media\&token=4729c607-dc32-4b70-8f3d-e66880e7654c)

В это же время начнет выполняться сценарий во второй записи очереди:

![](https://1283378397-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LACZmmM2xUWbZxyRr4s%2Fuploads%2Fm7AoGNrYd79CAs694Svq%2F%D1%81%D0%BB%D0%B5%D0%B4.png?alt=media\&token=2f8540a8-62a1-4879-a40d-7b9fff9b72c0)
