Registration-service.md
Назначение
Получать запрос на регистрацию ЮР лица, формирование набора sag, их отправка на выполнение и ожидания их выполнения, осуществление ответа на gateway по факту выполнения или ошибки выполнения запроса.
Структура БД, в которой буду хранится данные о saga-х
Таблица описания sag
saga_uuid | status | type | name | saga_data |
---|---|---|---|---|
uuid | numeric(3) | numeric(3) | varchar(64) | json |
Статус имеет следующие значения:
0
(undefined)10
(created)20
(in progress)30
(completed)40
(fallback in process)50
(fallback completed)250
(fallback error)255
(error)
Поле type
- указывает на тип операции, в которой задействована sag-а:
- 0 (неизвестное)
- 1 (регистрация ЮР лица)
- 2 (создание счёта для ЮР лица)
- 255 (ошибка)
При получении удачно выполненного event-а убираем его из списка. В случае, когда все event-ы выполнились, то меняем состояние саги с 20 на 30. В случае, если пришёл неудачный event, то меняем статус саги на с 20 на 255.
Поле saga_data
хранит все данные, необходимые для его event-ов, а также данные, которые могут быть получены в результате выполнения event-а. Формат json поля следующий
{
"name_1": ...,
...
"name_n": ...
}
Таблица зависимостей sag
current_saga_uuid | next_saga_uuid | acc_connection_status |
---|---|---|
uuid | uuid | numeric(3) |
Значения поля status
:
0
- неизвестный10
- ожидает выполнения текущей саги20
- выполнена удачно30
- откат255
- ошибка
Данная таблица отвечает за то, что отвечает за последовательность саг в запросе. Т.е. следующая сага не может быть запущена, пока в данное таблице не будет записей с uuid саги next_saga_uuid
.
Таблица событий
event_uuid | saga_uuid | event_status | event_name | event_is_roll_back | event_required_data | event_result | event_rollback_uuid |
---|---|---|---|---|---|---|---|
uuid | uuid | numeric(3) | varchar(64) | bool | json | json | uuid |
Содержит события саг. Статус имеет следующие значения:
0
(undefined)10
(created)20
(in progress)30
(completed)40
(fallback in process)50
(fallback completed)250
(fallback error)255
(error)
В event_required_data
лежит список необходимых полей для данного event-а. Формат следующий:
{
[
"name_1",
...
"name_n"
]
}
Данные берутся из поля saga_data
из данных sag-и.
В event_result
лежит результат, полученный в ответ от другого сервиса.
event_rollback_uuid
- поле, в котором лежит uuid того event-а, которое откатывает текущее.
Список запросов, необходимых для репозитория:
- создание sag-и
- удаление sag-и
- обновление sag-и
- создание event-a
- удаление event-а
- обновление event-а
- создание связи между sag-ми
- удаление связи между Sag-ми
- обновление статуса связи между sag-ми
- получение списка uuid всех event-ов sag-и
- получение списка связей текущей Sag-и, где текущая sag-а зависит от других
- получение списка связей текущей sag-и, где от текущей Sag-и зависят другие
Механизм sag
Список названий event-ов
- Сервис счетов
- Reserve account
- Create acccount
- Open account
- Сервис пользователей
- Create user
- Add account to user
Список выполняемых операция и sag в них с event-ми
- Create user (простая)
Зависимость sag
: create_userSaga №1
: create_userEvent-ы
: Create user
- Add account to user (составная)
Зависимость sag
: reserve_acc -> create_acc -> open_acc_and_add_to_userSaga №1
: reserve_accEvent-ы
: Reserve acc
Saga №2
: create_accEvent-ы
: Create acc
Saga №3
: open_acc_and_add_to_userEvent-ы
: Open acc + Add account to user
Формирование sag дерева sag операции
Структура одноименных с операцией Sag внутри сервиса будет представляться в виде уровней дерева:
1)Выбрать следующую sag-у текущего уровня дерева.
2)Создать выбранную пустую sag-у со статусом 0
.
3)Добавить uuid созданной sag-и в map с номером sag-и в дереве.
4)У текущей sag-и есть зависимость от других sag? Если да, то идем в пункт 5, иначе, идём в пункт 8.
5)Выбрать следующую sag-у, от которой зависит текущая.
6)Связать текущую sag-у с зависимой по номеру sag-и в map-е.
7)Зависимая sag-а была последней? Если нет, то идём в пункт 5, иначе идём в пункт 8.
8)Создать события со статусом созданных (10
), которые должны быть в sag-e.
9)Sag-а является последней в уровне дерева? Если нет, то идём в пункт 1, иначе идём в пункт 10.
10)Уровень дерева является последним? Если нет, то идём в пункт 11, иначе в пункт 12.
11)Переходим на следующий уровень дерева. Идём в пункт 1.
12)Проходимся по map-е и изменяем статус sag на созданный (10
)
Работа механизма sag
Обработка событий и sag происходят в go-рутинах. Так что алгоритм рассчитан на много поточное выполнение.
1)Текущая Sag-а зависит от других саг? Если да, то идём в 2, иначе идём в 5.
2)Все sag-и, от которых зависим выполнились? Если да, то идём в 5, иначе идём в 3.
3)Ожидание. Идём в пункт 2.
4)Изменяем статус текущей sag-и на исполняемую (20
).
5)Проход по всем событиям sag-и, изменение их статуса на исполняемую (20
) и отправка соответствующих им запросов на соответствующие сервисы.
6)Ожидание получения ответов на event-ы.
7)Полученный ответ на event удачный? Если да, то идём в пункт 8, иначе идём в 17.
8)Изменяем статус event-а на выполненный (30
).
9)Event откатывает другой (флаг event_is_roll_back
)? Если да, то идём в пункт 27, иначе идём в пункт 10.
10)На все event-ы sag-и получен ответ? Если да, то идём в пункт 11, иначе идём в пункт 6.
11)Все события sag-и выполнились удачно, т.е. имеют статус выполненной (30
)? Если да, то идём в пункт 12, иначе идём в пункт 28.
12)Изменение статуса sag-и на выполненное удачно (30
).
13)От текущей sag-и зависят другие sag-и? Если да, то идём в пункт 14, иначе идём в пункт 15.
14)Изменение статуса связи между текущей sag-ой и зависящих на выполненную удачно (20
).
15)Все sag-и выполнились? Если да, то идём в пункт конец
, иначе идём в пункт 16.
16)Переключаемся на следующую невыполненную sag-у (речь идёт про многопточность). Идём в пункт 1.
17)Изменение статуса event-а на ошибку (255
).
18)Event откатывает другой (флаг event_is_roll_back
)? Если да, то идём в пункт 19, иначе идём в пункт 20.
19)У откатываемого event-а меняем статус на ошибка в откатывании (250
).
20)Sag-а уже откатывается? Если да, то идём в пункт 22, иначе идём в пункт 21.
21)Изменение статуса sag-и на откат (40
).
22)В sag-е есть удачно выполненные (30
) event-ы, не являющихся обратными (флаг event_is_roll_back
)? Если да, то идём в пункт 23, иначе идём в пункт 10.
23)Выбрать следующий удачно выполненный (30
) event, поменять статус на откатываемый (40
).
24)Создать откатывающий event к текущему в статусе созданного (10
) и с поднятым флагом откатывания другого (event_is_roll_back
).
25)Привязать созданный event к откатываемому.
26)Изменить статус созданного event-а на в процессе
(20
) и отправка соответствующего запроса на соответствующий сервис. Идём в пункт 22.
27)Изменение статуса откатываемого event-а текущим на удачный откат (50
). Идём в пункт 10.
28)Текущая сага имеет ошибки в событиях (255
)? Если да, то идём в пункт 29, иначе идём в пункт 30.
29)Изменение статуса sag-и на ошибочную (255
).
30)Текущая сага имеет ошибки откатывания в событиях (250
)? Если да, то идём в пункт 31, иначе идём в пункт 32.
31)Изменение статуса sag-и на ошибочную в откатах (250
).
32)Текущая sag-а зависит от других sag? Если да, то идём в пункт 33, иначе идём в пункт 35.
33)Изменение статуса связи между текущей sag-ой и теми, от которых зависит текущая на откат (30
).
34)Переход во все sag-и, от которых зависит текущая sag-а.
35)Есть sag-и, которые завися от текущей и связь между текущей и зависимой в статусе выполнено удачно (20
)? Если да, то идём в пункт 36, иначе в пункт 21.
36)Переход во все sag-и, которые зависят от текущей со статусом связи выполнено удачно
(20
). Идём в пункт 35.
конец
)Завершилась обработка всех sag операции
Пример
Уровень бизнес логики
Уровень sag
- создать sag-у
- откатить sag-у
- удалить sag-у
- создать event
- откатить event
- удалить event
- отправить запрос, реализующий event
- обработать ответ на event
Уровень операция бизнеса
- создать пользователя
- открыть счёт для пользователя (будет реализовываться после первой операции)