Про событийный дизайн
Одним из самых полезных инструментов проектирования для меня всегда была событийная архитектура. И это как раз та штука, которую ни одна агентская ии-система сама пока делать не умеет, тут нужен опытный специалист, искушённый в вопросах проектирования.
Про проблему
Любая сложная логика изменения объекта, которая подразумевает возможность конкурентного доступа к данным (гонок) из разных потоков или зависит надёжности внешней системы - это всегда больно.
По классике мы должны решать это так: садимся и считаем, что будет, если это случилось раньше, чем вот это. Что будет, если вот это начало обработку, но сломалось на полпути. Это нормальный подход, рабочий вариант, можно и так, но, в итоге, может получиться сложно, ненадёжно и, со временем, есть вероятность, что оно начнёт ломаться и требовать все больших усложнений.
Пример
Для тех, кто пока не понял, про что речь. Вот у вас есть ресурс какой-то. Не знаю, товар на складе в вашем маркетплейсе. И вот его могут покупать десятки и сотни человек в день. Как сделать так, чтобы из-за гонки кто-то не купил закончившийся товар?
Или что делать, если надо отправить заказ на доставку, списать деньги, списать товар из остатков, а где-то посредине что-то сломалось? Денег нет, например, или апи логистов сдохло и не получило запрос. Или приложуха умерла на полпути, потому что новый релиз начал накатываться. Или какой-то вайбкодер всю базу выгрузил в оперативку и наступил OME.
Туда же относится и другая распространённая беда, которая очень хорошо ломает статусные модели и стейт-машины: когда ответы и запросы приходят не в том порядке, в котором они были отправлены.
События
Короче, все это пипец нетривиально, задачка со звёздочкой. Но это все пока вы не начинаете относиться ко всем вышеописанным вещам в системе, как к событиям, и оперировать не просто объектами, а объектами, агрегирующими события. Не "товар такой-то в таком-то статусе, на складе 57 штук", а "товар такой-то; поставки: 1 февраля 50 штук, 1 марта 100 штук; списания: 29 марта в 14:02 2 покупки, 29 марта в 12:22 1 покупка, 22 марта в 23:59 100 покупок". Тот самый event sourcing.
И то же со взаимодействиями: не дернул десять апишек, когда пользак нажал кнопку купить, а сохранил его намерение купить. И дальше шедуллеры побежали деньги списывать, логистам заказ передавать, остатки минусовать, баллы лояльности начислять и вот это все. Это вы, скорее всего, знаете под соусом transaction outbox.
Вот все это, на самом деле, про одно и то же: событийные архитектуры, реактивные системы. Тут работает чисто парадигменная идея из функционального программирования: вы не управляете состоянием, вы просто записываете события, представляя коду возможность самостоятельно разобраться с тем, что же всё-таки произошло.
С таким подходом сильно проще разруливать гонки, вопросы с порядком событий и проблемы недоступности. Бонусом автоматически решаются вопросы аудита, упрощается дебаг и разруливание проблем в проде.
Минусы
1. На очень простых моделях это безусловно оверкилл.
2. При большой нагрузке база забивается очень быстро, что требует внимательной работы с запросами, партиционированием, архивированием и слепками данных.
3. Это не общепринятый подход, поэтому частенько можно встретить сопротивление предложениям решить проблему таким образом.
К счастью, команды, как правило, в условиях экстремальной нужды приходят к подобным решениям рано или поздно, часто даже не осознавая, что их решение - это та самая событийная архитектура.
Post #74
1.07K
- 👍 7
- ❤ 6
- 🔥 5