Привет всем) Хочу проконсультироваться. По поводу очередей. (Думаю сделать относящийся к рабочим задачам pet-project, во имя пропоганды эликсира).
Допустим, есть Phoenix (ради API, PubSub). Хранилище - Postgres (чтоб все четко было). Задеплоен с libcluster чтоб не тащить Redis для PubSub и можно было global GenServer сделать. Деплоится будет в k8s.
Есть сущность, допустим магазин. Магазины создаются динамически, но не удаляются (append only). Есть эндпоинт который принимает события в магазине. По событиям строятся репорты. Одно из возможных событий - сгенерировать отчет и сохранить в БД.
Нужно: не терять события, но максимально быстро отвечать из эндпоинта. Сам эндпоинт данных не возвращает, т е обновление аггрегатов, построение репортов можно делать в фоне.
В рамках одного магазина можно параллельно обрабатывать только одно событие.
Соответсвенно, вижу такую структуру:
- есть DynamicSupervisor
- под ним global GenServer'ы - каждый отвечает за свой магазин. При добавлении магазина стартует новый GenServer.
- когда приходит событие - сохраняем его в БД, шлем cast ген-серверу магазина, отдаем юзеру OK
- ген-сервер магазина обрабатывет сообщения и (тразакцией с локом) обновляет в БД статус события на "обработано", иногда шлет сообщение в PubSub (нужно для другой фичи)
Oban не подходит, т к хочется чего-то максимально легковесного и нужны только динамические очереди с capacity = 1. B хочется обойтись минимумом реквестов к PG.
На случай потерянных кастов можно иметь периодическую задачу (Process.send_after или quantum), которая будет искать аномалии в базе и дообрабатывать пропущенные сообщения (бизнес-логика позволяет).
Вопрос: что может пойти не так и где надо быть крайне осторожным? Хочется сделать быструю, надежную и достаточно простую систему чтобы понтоваться перед JS/Python разработчиками XD