# 03. IPC И Логические Сессии Статус: не начат. Зависимости: 01, интерфейсы маршрутизации 02. ## Цель Отделить TCP-соединение от состояния consumer у владельцев. Обеспечить межпроцессный обмен без общих указателей, неограниченных буферов и неявного повторения команд. ## Задачи 1. Реализовать неблокирующий IPC на Unix domain sockets с явным framing; выбрать stream или message-oriented транспорт с учётом крупных bodies и платформ. 2. Определить versioned envelope: topology fingerprint, поколения endpoints, session ID, request ID, opcode, размеры метаданных и body. Не сериализовать C-структуры с padding/указателями как wire contract. 3. Ввести session identity, уникальную в пределах поколения frontend, и идентичность запуска supervisor. Защититься от повторного использования PID/FD и запоздалых сообщений. 4. Хранить у frontend транспортное состояние, `use`, watch list и маршруты резерваций. Хранить у владельцев логические ссылки, ожидания и принадлежащие сессиям jobs. 5. Сохранить порядок команд и ответов на одном клиентском соединении, включая pipelined input. Не считать IPC request ID разрешением менять порядок протокола. 6. Ввести лимиты на размеры frames, входящие запросы, ожидающие ответы и body buffering. Превышение лимитов вызывает backpressure/задокументированный отказ, а не переполнение памяти. 7. Определить отмену reserve и detach сессии при disconnect, half-close, IPC failure и смерти frontend. Повторный detach должен быть безопасен; старый attach не должен отменять cleanup. 8. Определить управление памятью ответа: тело job, передаваемое медленному клиенту, остаётся доступным после timeout/delete исходного job. Копия или явная pin/reference имеют ограниченный срок жизни. 9. Не повторять мутации после неизвестного результата. Если предусмотрены повторы в живом канале, обеспечить дедупликацию в ограниченном окне с определённым моментом освобождения записей; не обещать сохранение dedup после crash без отдельного журнала. ## Межвладельческие Резервации Одной Сессии Ограничение одной наблюдаемой tube не исключает сохранённые резервации у нескольких владельцев. Это возникает после смены watch list или `reserve-job`. - Owner остаётся источником истины о job и его TTR. - При ожидании нового reserve необходимо учесть ближайший deadline всех резерваций сессии, а не только текущей tube. - Спроектировать обновления после `touch`, release/delete/bury, timeout и новой резервации, чтобы frontend/coordinator не принимал решения по устаревшему deadline. - Описать упорядочивание событий job available, timeout, `DEADLINE_SOON`, disconnect. Только один из конкурирующих результатов завершает ожидающий запрос. - Согласовать cleanup остальных владельцев при гибели одного owner и закрытии затронутой клиентской сессии. Это координация состояния одной сессии, а не межшардовый выбор минимального priority из нескольких watch tubes. Смешивать эти задачи нельзя. ## Приёмка - Тесты partial read/write, объединённых frames, некорректных длин, oversized body и разрыва IPC посреди сообщения проходят без повреждения состояния. - Старые поколения, неизвестные session IDs и несоответствующая топология отклоняются до мутации. - Медленный client/frontend не вызывает неограниченного роста памяти или блокировки всех owners. - Disconnect во время `put`, ожидания reserve, выдачи job и передачи большого body корректно освобождает ресурсы. - Авария frontend очищает все его сессии и резервации за установленное в 01 время; явно отличать завершившийся процесс от временно медленного. - Потеря ответа на `put` не вызывает скрытого второго `put`; неоднозначный результат виден как ошибка соединения по контракту. - Переключение tube при живой резервации, `reserve-job` другой tube и последующие `touch`/`DEADLINE_SOON` проверены через разные owners. ## Точки Кода `dat.h:Conn/Socket/Job`, `conn.c`, `prot.c:conn_process_io/conn_timeout/reply_job`, платформенный event loop. Новый IPC-модуль должен иметь самостоятельные тесты framing и жизненного цикла.