Continous integration / Tests (push) Canceled after 0s
Testing clients / Build beanstalkd (push) Canceled after 0s
Continous integration / Docker build (push) Canceled after 0s
Testing clients / Test Pheanstalk PHP (push) Canceled after 0s
Testing clients / Test Greenstalk Python (3.9) (push) Canceled after 0s
Testing clients / Test Pystalk Python (3.10) (push) Canceled after 0s
10 KiB
10 KiB
Критический Контекст
Статус И Источники
- Здесь находится исходный Beanstalkd 1.13 на C99. Многопроцессная архитектура ниже принята как направление доработки, но ещё не реализована.
- Постановка: epics/00-overview.md. Открытые решения перечислены в epics/01-contract.md; не считать их уже утверждёнными.
- Исходные контракты:
README.md,doc/protocol.txt,doc/beanstalkd.ronn,doc/beanstalkd.1. Каталог называетсяdoc, неdocs. doc/beanstalkd.1и HTML генерируются изdoc/beanstalkd.ronn. При изменении CLI обновлять исходник руководства и производные документы штатным способом.- Сохранять приоритеты проекта: стабильность, исправление ошибок, ясность, затем производительность; см.
CONTRIBUTING.md.
Принятое Решение
- Архитектура: процессы-владельцы групп tubes на одном хосте, frontend для TCP/протокола, IPC между frontend и владельцами, supervisor для управления процессами.
- Каждая tube имеет одного владельца; один владелец обслуживает несколько tubes. Все изменения её заданий и планирование выполняются последовательно в event loop владельца.
- У каждого owner slot отдельные состояние в памяти и WAL. Owner slot является стабильным логическим идентификатором, а не PID.
- На первом этапе consumers не резервируют задания одновременно из нескольких наблюдаемых tubes. Допускается временный watch list из нескольких tubes при настройке, например
watch target,ignore default. На моментreserve/reserve-with-timeoutнаблюдаемая tube должна быть одна. - Реакция на неподдерживаемый multi-watch reserve требует явного протокольного решения. Нельзя молча выбрать одну tube или выдать выдуманный стандартный ответ.
- Одна наблюдаемая tube не означает один job, одну резервацию или одного владельца на всё время TCP-сессии. Переключение watch list и
reserve-jobмогут оставить у сессии резервации разных владельцев. Не вводить дополнительные ограничения без согласования. - Одна горячая tube остаётся последовательной. Масштабируется совокупность независимых tubes, а не выполнение пользовательских задач внешними consumers.
Владение Динамическими Tubes
- Постоянный дескриптор каждой tube не нужен. Объект появляется при
use,watch, инициализацииdefaultили восстановлении заданий и удаляется после исчезновения удерживающих ссылок. - Задание в любом живом состоянии, включая reserved, удерживает tube. Ссылки от удалённых сессий должны учитываться у владельца; авария frontend должна их освобождать.
- Владение определяется до создания объекта:
partition = stable_hash(tube_name) % PARTITION_COUNT, затемowner_slot = partition_map[partition]. - Алгоритм hash, параметры, число разделов и карта одинаковы у всех процессов и стабильны между перезапусками с данными. Их точный формат задаётся в эпиках 01 и 02.
- Конкурентный claim отдельной tube не нужен: все обращения с одним именем попадают одному владельцу; он локально выполняет find-or-create.
- Маршрутизация сама по себе ничего не создаёт. Например,
stats-tubeиpause-tubeнеизвестного имени должны сохранитьNOT_FOUND. - Жизненный цикл объекта tube не меняет принадлежность имени. Повторное создание использует того же владельца.
- Одновременно активен не более одного процесса на owner slot. При падении перезапускается тот же slot; нельзя направлять его имена к другому живому владельцу как обычный failover.
- Карта распределения фиксирована на первом этапе.
hash(name) % live_process_count, автоматический rebalance и переназначение при сбое запрещены. Миграция требует отдельной процедуры.
Инварианты Реализации
- Не передавать
Job*,Tube*,Conn*,File*через IPC. Использовать сериализуемые ID, поколения процессов/сессий и явное владение данными. - Сохранять последовательность команд и ответов на TCP-соединении, текущие проверки владения резервацией, priority/FIFO внутри tube, delay, TTR, timeout,
DEADLINE_SOONи освобождение резерваций при disconnect. - У задания не может быть двух действующих резерваций; один запрос reserve даёт не более одного результата. Повторное выполнение внешним consumer после TTR допустимо: exactly-once не обещается.
- ID должны быть уникальны в логическом сервере, маршрутизируемы и безопасны при частичном перезапуске.
job_pri_less()использует ID для FIFO; новый формат ID не должен нарушать порядок внутри tube. - IPC обязан иметь framing, лимиты памяти, backpressure, отмену ожиданий и защиту от устаревших сообщений. Не повторять автоматически
putили другую мутацию с неизвестным результатом. - Смерть владельца, frontend и supervisor является частью контракта, а не только эксплуатационной деталью. Недоступность владельца не равна
NOT_FOUND. - Не делить существующий WAL между независимыми writers и не снимать блокировку каталога ради многопроцессности. Изменение
Jobrecтребует следовать правиламWalverвdat.h. - Не обещать более сильную durability, чем реализует выбранный режим
-b,-f,-F. Успешный IPC-ответ сам по себе не означает fsync. - Политика сохранения отдельного legacy-режима, включения новой архитектуры и переноса старого WAL согласуется в эпике 01 до изменения запуска и форматов. Не считать поддержку двух режимов уже утверждённым объёмом и не ломать существующее поведение/данные без явного решения.
Карта Кода
| Область | Файлы и точки |
|---|---|
| Запуск и event loop | main.c, serv.c:srvserve, платформенные linux.c, darwin.c, freebsd.c, sunos.c |
| Протокол, scheduler, timers | prot.c:dispatch_cmd, process_queue, prottick, conn_timeout |
| Сессии и резервации | conn.c:conn_reserve_job, connclose, dat.h:Conn |
| ID и jobs | job.c:next_id, all_jobs, job_pri_less; dat.h:Job, Jobrec |
| Динамические tubes | tube.c:tube_find_or_make, tube_iref, tube_dref |
| WAL и восстановление | walg.c, file.c, serv.c:srv_acquire_wal, prot.c:prot_replay |
| Тесты | testserv.c, testjobs.c, testheap.c, testms.c, testutil.c, ct/ |
Проверки
- Сборка:
make; регрессии:make check; существующие микробенчмарки:make bench. - Команды требуют поддерживаемого Unix-окружения и toolchain. Нативный Windows не заявлен как поддерживаемая платформа; наличие WSL/контейнеров проверять, а не предполагать.
make benchне заменяет end-to-end нагрузочный тест многопроцессного сервера.- Для каждой реализации проверять один и несколько owner slots, ошибки IPC, disconnect, TTR, аварии и восстановление WAL. Критерии:
epics/07-validation.md. - Не выдавать статический анализ за измеренный выигрыш и не отмечать эпики завершёнными без проверок.