booblik
Docs

README

booblik — брокер сообщений на Kotlin/JVM с хранением в append-only логе. Документация разложена по слоям: от «почему архитектура именно такая» к «как это устроено на проводе» и «что внутри модуля».

[ Research — почему так; что проверено, что гипотеза ]

[ Feature — что делает система и зачем + BDD = критерии приёмки ]

[ Protocol — контракт на проводе ]

[ Service — зона ответственности модуля, грабли ]
СлойПапкаОтвечает на вопрос
Researchresearch/почему архитектура именно такая; что проверено, что гипотеза
Featurefeatures/что делает система и зачем, BDD-сценарии = критерии приёмки
APIapi/протокол на проводе
Serviceservices/зона ответственности модуля, конфиг, грабли

Слоя screens/ нет: клиента с интерфейсом у брокера не бывает.

Оговорка про статус

Инвариант: main описывает то, что есть.

Закрыты все вехи, M0–M11: хранилище, сеть, протокол и клиент, эксплуатация, проверки корректности, подписки и долгий FETCH, поставка (образ в GHCR, клиент в reposilite), образец из четырёх сервисов. Сегмент, разреженный индекс, две реализации записи, партиция с роллингом и retention, восстановление после рестарта, актор записи с батчами и групповым коммитом; собственный acceptor на селекторе, бинарный протокол, FETCH мимо кучи; несколько топиков, конвейерное соединение, Producer с накоплением, Consumer со своей позицией и подписка как Flow; конфигурация с проверкой при старте, метрики, дистрибутив и образ со своей проверкой здоровья. 104 теста — оба пути записи и оба транспорта прогоняются через один набор утверждений.

Потолок по проводу — 1,4 млн записей в секунду, брокер отдельным процессом, генератор на другой машине (замер 16). Раннее число 267 тысяч снималось со стендом внутри JVM брокера и им же и было ограничено.

Брокер запускается, обслуживает и переживает рестарт — это проверяет ci/smoke.sh в гейте.

Чего не будет: создания топиков (набор партиций задаётся при старте), TLS и сжатия — они несовместимы с zero-copy (§1.2), — и отставания потребителя в метриках: брокер не хранит позиции читателей.

Утверждения, которые по ходу работы перестали быть верными, — их стоит знать до чтения: барьер через маппинг оказался не барьером (§1.9), индексный файл не нужен (§1.10), короткий замер завышал маппинг в десять раз (§1.11), а zero-copy ничего не даёт ниже гигабайта в секунду (замер 7). Правьте по источнику, а не по памяти.

Ресёрч отделяет прогоны (скомпилировано и запущено) от чтения исходников и от гипотез. Правите утверждение — перепроверяйте источник, а не соседний документ.

Документы

Research

  • research-architecture — проверенные факты, решения, риски. Точка входа для любого, кто берётся за задачу. Две центральные посылки исходного драфта здесь опровергнуты по исходникам: Kafka пишет лог не через mmap (§1.1), а Ktor не отдаёт SocketChannel (§1.3).
  • research-usecases — за чем к брокеру приходят и что из этого строится в booblik, а что рядом с ним. Отвечает на вопрос про очередь задач: она не становится фичей брокера (Р11), а компактификация закрыта конструкцией — ключа нет на проводе (Р12).
  • source-draft — исходный драфт задания, зафиксирован как есть. Не руководство к действию: расхождения разобраны в разделе 2 ресёрча.

Образец

  • dev/ — четыре сервиса в docker compose, показывающие booblik в работе: раздача партиций и позиция у потребителя, очередь задач как протокол поверх лога, проекция (read model) и ретранслятор в Kafka и обратно. Собирается от опубликованного клиента и образа, поэтому ловит дефекты поставки, которых не видит сборка «всё вместе»: так нашлись 0.1.1 (корутины в runtime) и 0.1.2 (аккумулятор терял запись).

Совместимость клиентов

  • conformance/ — чем проверяется клиент на любом языке. Golden-вектора для двух алгоритмов, которых нет на проводе, но которые обязаны совпадать: партиционер (ключ до брокера не доходит) и CRC32C (на zero-copy-пути его проверяет только клиент). Плюс гарнесс из 13 проверок против живого брокера — со своей реализацией протокола, потому что проверять продюсера им же самим нечем. Контракт клиента и роли — там же; спецификация алгоритмов — §7 протокола.

Клиенты

  • clients/ — паблишеры на Go, Python, Node.js и .NET (переписаны начисто, ноль зависимостей) плюс Kotlin/Native — таргет, а не пятая реализация: он делит кодек с JVM-клиентом через :booblik-protocol. У каждого языка своя грабля в одной строке хеша, и это главный аргумент за golden-вектора.

Производительность

  • benchmarking — методика, профиль рантайма, правила и все снятые числа. Веха не закрывается без строки в этом документе.

Features

  • feature-subscribe-and-publish — подписка на топик и публикация: follow/replay, долгий FETCH, хендл топика с маршрутизацией по ключу. Веха M7 закрыта, документ описывает существующее поведение.
  • feature-append-and-fetch — записать в лог и прочитать по оффсету. Это весь брокер; всё остальное существует ради скорости этих двух операций.

API

  • protocol-wire — бинарный протокол: кадр, PRODUCE, FETCH, коды ошибок.

Services

  • booblik-core — хранение: сегмент, индекс, две записи, transferTo.
  • booblik-client — клиент и общий кодек.
  • booblik-net — провод: селектор, кодек, сессии, два транспорта.
  • booblik-app — запуск: конфигурация, метрики, retention, дистрибутив.
  • booblik-benchmark — числа: JMH и пробы.

Бэклог../BACKLOG.md, задачи M-NN по вехам M0…M11, все закрыты. Каждая веха заканчивается строчкой итога: что вышло сверх плана и какая гипотеза не подтвердилась.

Соглашения

  • id во frontmatter = имя файла.
  • Главный потребитель — Claude Code. Каждый документ даёт якоря кода: путь к файлу, а не пересказ содержимого. Путь остаётся верным, копия протухает.
  • Один документ = одна сущность.
  • Числа в документах — только снятые прогоном, с указанием хоста и режима сброса. Без режима сброса число бессмысленно, а не неточно.
  • Гипотезы называются гипотезами; отклонения от драфта называются отклонениями.
  • Код по-английски, документация по-русски. Идентификаторы, имена задач Gradle и сообщения об ошибках — вербатим как в коде.

On this page