---
# System prepended metadata

title: Планировщик

---

# Планировщик

## Предпосылки

В **Bridges** на данный момент есть проблема, связанная с отправкой транзакций. В случае возникновения ошибки при отправке транзакции в сеть, транзакция просто будет потеряна.

Рассмотрим случаи, при которых это можно возникнуть:

* Потерялось подключение к ноде блокчейна
* Установлена низкая максимальная комиссия при отправке транзакции
* Указано недоступное кол-во токенов при переводе (закончились токены в контракте, скорее всего требуется пополнение)

При возникновении таких ошибок необходимо попытаться повторно отправить транзакции и, возможно, изменить некоторые атрибуты транзакции. 

Также помимо отправки транзакций, делаются запросы с оповещениями на API фронтэнда. При отправке запросов могут вернуться ответы с неудачными статус кодами. В таких случаях тоже нужно обработать статус код и попробовать сделать повторную отправку запроса.

## Задачи планировщика

Планировщик должен уметь откладывать выполнение следующих работ:

* Отправка транзакции
* Отправка оповещения на API

При возникновении ошибки в работе планировщик должен пытаться выполнить работу заново, либо отложить ее выполнения на какой-то период.

Также работы могут зависить друг от друга, поэтому нужно задавать последовательность выполнения работ. Например, отправка оповещения должна происходить после отправки транзакции.

> **N.B** Задание последовательности также подразумевает, что должна откладываться целая цепочка невыполненных работ.

## Очередь работ

![Диаграмма очереди планировщика](https://i.imgur.com/fjq1Xek.jpg)

У планировщика должна быть очередь для работ, которая будет задавать последовательность их выполнения. Рассмотрим, какие операции должны быть доступны у очереди:

* Добавление работы в начало
* Добавление работы в конец

Операция для добавления в начало нужна, т.к. некоторые работы могут быть приоритетными. Например, в случае неудачного отправления транзакции, данная работа должна быть добавлена в начало очереди.

Очередь должна хранить работы в **Redis** в сериализованном виде. Чтобы в случае падения p2p ноды, можно было восстановить очередь.

Основной сложностью при сохранении работ в **Redis** является хранение параметров. У работы должна быть примерно следующая структура в очереди:

```json
{
    jobName: "job_name",
    timestamp: "2022-09-09T15:59:60-08:00",
    retries: 5,
}
```

Параметр *timestamp* - это время добавления работы в очередь.

Параметр *retries* нужен для того, чтобы контроллировать кол-во уже выполненных попыток. В случае если кол-во попыток изчерпано, тогда выполняется обработка неудачной ситуации.

Также код обработчика работы на Go, должен привязываться по имени работы. То есть должен быть примерно следующий метод или функция.

```go
func RegisterJob(jobName string, h JobHandler)
```

Хранения параметров можно сделать при помощи key/value пар в **Redis**. Только ключ должен быть составным в следующем формате.

```
'params'/job_name/timestamp/param_name
```

> **N.B.** Составные части указанные в одинарных кавычках записываются в ключ как есть. В параметрах без кавычек происходит подстановка. Например, params/send_transaction/..., в случае если имя работы - send_transaction. 

При таком хранении код обработчика на Go может считать работы и ее параметры из **Redis** и затем проводить дальнейшую обработку. Возможно, в конце выполнить рекурсивное добавление новой работы в очередь (см. раздел ниже).

## Рекурсивные работы

Рекурсивное выполнение работ - это одна из идей, которая может позволить задать последовательность выполнения работ.

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

> **P.S.** Данная возможность подразумевает, что обработчик работы должен принимать планировщик в качестве параметра для ее реализации.

## Архив работ

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

Архив по-сути является такой очередью работ, только с одной особенностью работы из этой очереди достаются с определенным промежутком, например, раз в пол часа (данный параметр должен задаваться при создании).

Затем работа, которую достали из архива, должна быть добавлена в начало очереди или в конец в зависимости от приоритета.

Возможно, сделать несколько архивов, которые откладывают выполнение работ на разное время. Например, один архив откладывает на пол часа, а другой уже на сутки. То есть сначало работу отложили на пол часа, потом перенесли в очередь, произошла неудача, тогда работу переносят в архив с промежутком на сутки.