Browse Source

Document live NCD stream delivery, wire format and limits

master
evgeny 6 days ago
parent
commit
007f5d21b2
  1. 64
      doc/stream.txt
  2. 10
      doc/tasks.md

64
doc/stream.txt

@ -200,7 +200,7 @@ ETCP обеспечивает переповторы, порядок, мульт
- END — последняя пачка и штатное завершение содержимого источником. - END — последняя пачка и штатное завершение содержимого источником.
handle — ненулевой 64-битный ID, назначаемый получателем. handle — ненулевой 64-битный ID, назначаемый получателем.
Предлагаемый простой механизм защиты от повторов: возрастающие handles в пределах stream-сессии пира, Механизм защиты от повторов: возрастающие handles в пределах stream-сессии пира,
новые SUBSCRIBE отправляются по порядку в одной управляющей FIFO. новые SUBSCRIBE отправляются по порядку в одной управляющей FIFO.
Номер выделяется непосредственно при постановке нового SUBSCRIBE в эту FIFO, после готовности подключения; Номер выделяется непосредственно при постановке нового SUBSCRIBE в эту FIFO, после готовности подключения;
параллельные ожидания NCD/INFO не резервируют номера, которые позже нарушили бы порядок отправки. параллельные ожидания NCD/INFO не резервируют номера, которые позже нарушили бы порядок отправки.
@ -518,9 +518,28 @@ Stop/destroy выполняются по правилам ядра, вне callb
Общий ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS. Общий ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS.
Лог общего прогона: /tmp/stream-service-check.log (107 с). Лог общего прогона: /tmp/stream-service-check.log (107 с).
[ ] Сетевая выдача: [+] Сетевая выдача — 11.10.2026:
raw/router IDs, INFO и поколения сессий, 64-битные handles, SUBSCRIBE/RENEW/CLOSED, stream_wire.c/h — big-endian формат, raw ETCP_ID_STREAM=0x07, routed ETCP_RT_ID_STREAM=0x39,
собственное владение NCD, REVERSE_REQ, курсоры кольца и общий начальный индекс от первого поставщика. INFO/ACCEPT с границами окна и путём, 64-битные эпохи/handles, отдельная подпись источника на END.
stream_network.c/h — собственный NCD owner пира, общий для его потоков/групп; ожидание его UP,
прямые SUBSCRIBE/ACCEPT/REJECT/DATA/GAP/RENEW/UNSUBSCRIBE/CLOSED/END, routed REVERSE_REQ/CLOSED.
Новые handles назначаются при постановке SUBSCRIBE в общую FIFO; watermark защищает от закрытых/старых запросов.
Первый проверенный DATA с конца устанавливает общий N; прочие latest-выдачи ждут его и запрашивают конкретный N.
Повторный stream_receive_restart отменяет upstream старой попытки, оставляя кольцо/downstream;
старые receive handles отсоединяются и требуют close. Уже сохранённый первый блок также устанавливает новый старт.
DATA копируется из кольца только перед отправкой; пути сохраняются по каждому блоку и проверяются на LOOP.
Все выбранные upstream, прошедшие недостающую пачку, позволяют потребителю выдать явный GAP и продолжить.
END подписывает domain/ключ запуска/последний индекс; нельзя завершить выдачу до прохождения её последнего блока/пропуска.
Период RENEW=2с, аренда=6с, первая попытка=5с; reverse не чаще 1/с в этом сроке.
DOWN/REINIT, потеря членства и закрытие локальной подписки отменяют относящиеся выдачи;
закрытие одной группы/выдачи сохраняет чужое владение транспортом и другие группы на том же пиру.
test_stream_service расширен настоящей цепочкой источник -> relay -> получатель поверх ETCP,
общим индексом, новым bootstrap, FEC 6+2 после снятия двух субпотоков, GAP, LOOP, повторами SUBSCRIBE/reverse,
подписанным END, продлениями/таймаутом аренды и асинхронным REINIT.
Две группы с FEC 6+2 и 1+0 используют один ETCP: истечение выдач первой сохраняет DATA второй.
test_stream_core проверяет wire: все 64 бита, усечения, версии, пути/циклы и размеры.
Оба теста прошли под ASAN/LeakSanitizer с detect_leaks=1 и halt_on_error=1, без ошибок и остатка живых аллокаций.
Логи: /tmp/stream-network-asan-core.log и /tmp/stream-network-asan-service.log.
[ ] Планировщик отправки и разгрузка: [ ] Планировщик отправки и разгрузка:
одна очередь на пира, backpressure, ограничение памяти/возраста, A/D/X/Q, одна очередь на пира, backpressure, ограничение памяти/возраста, A/D/X/Q,
@ -530,7 +549,36 @@ Stop/destroy выполняются по правилам ядра, вне callb
пути/защита от циклов, стартовые 32 пробы, дальнейший темп 1/с и полный цикл не чаще 30 с, пути/защита от циклов, стартовые 32 пробы, дальнейший темп 1/с и полный цикл не чаще 30 с,
постепенный перенос с перекрытием, failover, несколько источников и независимое закрытие на общем ETCP. постепенный перенос с перекрытием, failover, несколько источников и независимое закрытие на общем ETCP.
Текущие компоненты включают основу данных, локальный API и Merkle/BGP-интеграцию в CHAT. Сетевая выдача подключена: stream_receive_open выбирает явного пира/субпоток/позицию,
Сетевая выдача DATA между stream-экземплярами ещё не подключена: test_stream_service передаёт блоки stream_receive_get_info сообщает handle/прогресс/причину, stream_receive_close снимает только свою выдачу.
во внутренний dispatcher явно, а опции распространяет настоящим Merkle-обменом поверх ETCP. Локальная подписка по-прежнему владеет кольцом; receive handle её не заменяет и закрывается отдельно.
Следующий этап — raw/router bindings, отдельные NCD-владельцы и REVERSE_REQ, выдачи из кольца с handles/арендой. Прямой dispatcher в старой части теста сохранён для изолированной проверки FEC и закрытия из callback;
новая часть проверяет реальные сетевые bindings и передачу через relay.
Следующий этап — метрики поставщиков/общей нагрузки, OVERLOAD с подтверждением 500 мс и оптимизатор проб/переноса.
17. Зафиксированный сетевой формат и пределы первого сетевого этапа
Все stream-числа на wire — big-endian, без packed-структур и зависимости от host byte order.
Заголовок raw (52 байта): cmd:1, version:1, command:1, subblock:1,
group_id:8, source_node_id:8, source_epoch:8, sender_epoch:8, receiver_epoch:8, handle:8.
INFO_REQ/RESP согласуют sender/receiver epochs; неизвестная receiver_epoch=0 допустима только при начальном INFO_REQ/reverse.
Подписанный routed payload содержит тот же заголовок; его group_id сверяется с реальной группой router,
sender берётся из end-to-end router metadata. DATA через routed service отвергается.
INFO_RESP/ACCEPT: actual_seq:8, first_available:8, last_available:8, n:1, r:1, block_size:2,
path_count:1, node_ids:8*path_count. В INFO actual_seq — последний доступный, в ACCEPT — фактический старт.
SUBSCRIBE: requested_seq:8; REJECT: reason:1 и для отказа SUBSCRIBE first_available:8,last_available:8.
RENEW: один header handle без payload (каждая кодограмма продлевает один элемент списка).
UNSUBSCRIBE/CLOSED: reason:1. DATA: path_count:1,node_ids:8*path_count,неизменяемый подписанный блок.
GAP: old_cursor:8,next_cursor:8, уведомление включает диапазон [old_cursor,next_cursor).
END: "stream_end":10,group_id:8,source_node_id:8,source_epoch:8,last_seq:8,Ed25519:64 — всего 106 байт.
UINT64_MAX в END означает пустой источник; запрос с конца пустого кольца явно отвергается (нет первого блока).
Предел пути — 32 узла. Сохраняются только реальные узлы пути; исходный {source} не требует отдельной аллокации.
Память пути отделена от 32-МБ бюджета данных и ограничена числом блоков кольца:
до (8 + 8*32) байт на блок плюс поля индекса и overhead allocator; источнику эта память путей не нужна.
64 stream-пира, 256 активных выдач всего и 64 на пира. Control FIFO — до 128 кодограмм,
каждая не больше 338 байт wire; DATA в ней не хранится. На пира один waiter общего send_input_q,
отправка по освобождению до пустого порога; курсоры downstream обслуживаются round-robin.
Эти пределы задают ограниченную память базовой выдачи. A/D/X/Q, возраст нагрузки и 500-мс OVERLOAD
подключаются следующим этапом; автоматический выбор/перекрытие поставщиков пока не запускаются.

10
doc/tasks.md

@ -16,8 +16,14 @@
Лог: /tmp/stream-service-test-final.log. Исправлена выявленная утечка BGP node_paths при удалении узла. Лог: /tmp/stream-service-test-final.log. Исправлена выявленная утечка BGP node_paths при удалении узла.
Общий ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS. Общий ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS.
Лог: /tmp/stream-service-check.log (107 с). Лог: /tmp/stream-service-check.log (107 с).
Следующий этап — сетевая выдача DATA: NCD/reverse, handles/аренда и курсоры кольца; 11.10.2026 подключена сетевая выдача raw ETCP через собственный NCD owner: INFO/поколения,
затем общий отправитель/перегрузка и оптимизация путей. handles/watermark, общий старт от первого DATA, курсоры/пути/GAP/LOOP, подпись END и аренда/RENEW.
Routed REVERSE_REQ/CLOSED подписываются end-to-end. Явные receive API позволяют открыть/закрыть выдачу и начать новую попытку.
Сетевая цепочка источник -> relay -> получатель, две группы/FEC на одном ETCP, GAP/restart,
повторы/reverse, END, lease timeout и REINIT прошли под ASAN/LeakSanitizer без ошибок/утечек.
Логи: /tmp/stream-network-asan-core.log и /tmp/stream-network-asan-service.log.
Wire и численные пределы зафиксированы в doc/stream.txt, раздел 17.
Следующий этап — метрики и перегрузка (500мс/rates/OVERLOAD), затем автоматические пробы/перенос/failover.
[+] **test_reality_tls: коллизии порта слушателя** — 10.10.2026: [+] **test_reality_tls: коллизии порта слушателя** — 10.10.2026:
В общем прогоне 140 passed, 1 failed: stcp_server_create не смог занять порт 34922, bind errno=98 (EADDRINUSE). В общем прогоне 140 passed, 1 failed: stcp_server_create не смог занять порт 34922, bind errno=98 (EADDRINUSE).

Loading…
Cancel
Save