Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Таблицы
Очередь - это собственная таблица сервиса: строка - сообщение, группа - очередь, а роли столбцов решают, когда строка готова к захвату и что делает исход.
Схема текстом
- email_jobs, таблица сервиса: Отложена retry_after впереди, готова после него; Готова в срок, не завершена, без аренды; В работе захват по priority, retry_after, затем id; Dead letter другая группа или другая таблица; Завершена processed_at задан или строка удалена; Столбцы по ролям: id, group, priority, partition_key, retry_after, attempt, processed_at, locked_until, headers, payload; любая роль, кроме id, необязательна
- Публикация через брокер или собственная вставка сервиса записывает одну строку → Отложена retry_after впереди, готова после него: retry_after впереди
- Публикация через брокер или собственная вставка сервиса записывает одну строку → Готова в срок, не завершена, без аренды: готова сейчас
- Отложена retry_after впереди, готова после него → Готова в срок, не завершена, без аренды
- Готова в срок, не завершена, без аренды → В работе захват по priority, retry_after, затем id: захват
- В работе захват по priority, retry_after, затем id → Готова в срок, не завершена, без аренды: retry()
- В работе захват по priority, retry_after, затем id → Отложена retry_after впереди, готова после него: retry_after(d)
- В работе захват по priority, retry_after, затем id → Dead letter другая группа или другая таблица: на пределе
- В работе захват по priority, retry_after, затем id → Завершена processed_at задан или строка удалена: ack, drop
- Группа - это очередь. Таблица без столбца group - одна очередь, её читает одна подписка на брокер
Крейт не создаёт таблиц и не выполняет миграций. CREATE TABLE пишет сервис, а структура
описывает таблицу для крейта: #[derive(Inbox)] читает описание из
атрибутов, а InboxTable с
InboxSpec - то же описание, написанное вручную. Каждую строку
пишет собственная реализация Publish сервиса, поэтому устройство
вставки тоже остаётся за сервисом.
Строка доступна для захвата при четырёх условиях, и каждое действует, только если в таблице есть
его столбец: строка входит в группу подписки, её retry_after прошёл, её processed_at пуст, и её
не держит аренда (locked_until пуст или прошёл). Захват берёт доступные строки в порядке
захвата: сначала priority, меньшее значение раньше, затем retry_after, затем id. Строка с
retry_after в будущем - отложенная задача: очередь не видит её, пока не придёт её время.
Имя подписки выбирает её очередь. В таблице со столбцом group это группа, и каждая группа -
отдельная очередь. В таблице без этого столбца имя обозначает всю таблицу. Один брокер открывает
одну подписку на очередь: вторая подписка на ту же таблицу и группу останавливает сервис при
старте с ошибкой
SqlxBrokerError::AlreadySubscribed.
Несколько брокеров или несколько экземпляров сервиса делят одну очередь, а форма захвата разводит
их строки.
То, что строка передаёт обработчику, зависит от двух ролей. Со столбцом payload строка в режиме
полезной нагрузки: обработчик принимает полезную нагрузку, декодированную кодеком. Без него строка
в режиме строки: обработчик принимает саму строку в том виде, в каком её прочитал драйвер. Столбец
headers хранит заголовки доставки в одном столбце: при фиче json это объект JSON со
строковыми значениями. Раскладка заголовков по столбцам читает их вместо этого из отдельных
столбцов, по столбцу на заголовок. Таблица без того и другого доставляет пустые заголовки.
«Сейчас» читается, когда захват выбирает готовые строки, когда переобработка откладывает строку и
когда ack её отмечает. По умолчанию его читает хост, через
SystemClock, и передаёт в собственном типе столбца. При
clock = DatabaseClock операторы вместо этого читают часы базы данных:
| База данных | «Сейчас» в операторе |
|---|---|
| PostgreSQL | statement_timestamp() |
| MySQL, MariaDB | UTC_TIMESTAMP(6) |
| SQLite | strftime('%Y-%m-%dT%H:%M:%f+00:00', 'now'), текст |
SQLite хранит время как текст и сравнивает его как текст, поэтому таблица там держит один формат
времени во всех строках. Форма аренды всегда читает часы хоста: таблица аренды на DatabaseClock
не компилируется по причине, которую называет страница Захват.
Как захват берёт строку в работу, описывает страница Захват, а что записывает каждый исход - страница Завершение.