<style> [data-reveal] { opacity: 1 !important; transform: none !important; } </style>

Lexora

Продакшн-бэкенд на Rust с событийным ядром: transactional outbox, фоновые воркеры и фронтенд на React, всё на Cloud Run.

Принадлежность
Заказной продукт, разработанный совместно. Red Sentra продолжает его сопровождать. Договорённости о собственности и партнёр остаются приватными.
Доступность
Живой продукт. Исходный код приватный.
Стек
Rust / React / Cloud Run / Background workers
Публичная витрина (откроется в новой вкладке)

Обзор этой системы от Red Sentra (откроется в новой вкладке)

Снимок публичного сайта-витрины Lexora.

Задача

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

Система

Бэкенд на Rust вокруг событийного ядра. Изменение состояния и порождаемые им события фиксируются вместе через transactional outbox, а фоновые воркеры забирают эти события и выполняют медленную работу вне запроса. Сверху фронтенд на React, и всё это работает на Cloud Run.

Моя роль

Архитектура бэкенда и реализация событийного ядра, дизайн outbox и воркеров, а также операционная история в проде.

Самое сложное

Гарантии доставки. Между записью в базу и уведомлением остальной системы есть окно, в котором падение теряет событие. Закрыть это окно без распределённой транзакции — это фактически весь дизайн.

Архитектурные решения

  1. Доставка как минимум один раз с идемпотентными потребителями. Дубликаты обходятся намного дешевле потерь, поэтому воркеры написаны так, чтобы спокойно видеть одно событие дважды.
  2. Очередь — это PostgreSQL. Kafka добавила бы целый операционный слой и второй домен отказов, о котором нужно думать, и всё равно потребовала бы outbox, чтобы быть атомарной с транзакцией, которую описывает, — так что в этой системе брокер не даёт ничего, чего уже не даёт таблица. LISTEN/NOTIFY отклонён как основной механизм по более простой причине: уведомления нигде не сохраняются, поэтому лежащий воркер пропускает их полностью.
  3. Согласованность со временем касается только побочных эффектов. Авторизация, сохранение назначений и состояние обучения остаются синхронными, поэтому ученику никогда не показывают расписание, которое не зафиксировано надёжно. Издержки очереди приняты, а не спрятаны: опрос добавляет около двух секунд задержки, когда система простаивает, а таблица outbox растёт, пока не появится задача очистки.

Текущее состояние

В проде. Red Sentra продолжает сопровождать и развивать его.