0.9.0
Итерация 4 плана аудита: шина сообщений и доставка cron/heartbeat.
Added
- Миграции
020_actor_pending_msg(SQLite + PG): таблица spillover для inbound-сообщений, не уместившихся в буфер актора. FIFO-порядок поid, индексidx_actor_pending_msg_session_key - Тип
store.ActorPendingMsgи методыSaveActorPendingMsg/ListActorPendingMsg/DeleteActorPendingMsgв SQLite/PG/Dual store - Метрики шины и актора:
Metrics.BusInboundDropped,Metrics.BusOutboundDropped,Metrics.ActorChFull,Metrics.ActorPendingSpilled+ новый блокbusв/api/v1/metricssnapshot - Singleton-доступ
metrics.Default()для использования из пакетов, не получающих*Metricsявно - WS-событие
system_message(поляsource_channel,session_key,chat_id,text,session_title) — рассылается при любом outbound из cron/heartbeat с непустым Content. UI (web/src/routes/chat/+page.svelte) обрабатывает наряду сsession_updated - Метод
WebSocketChannel.SendSystemMessage(sourceChannel, sessionKey, text, sessionTitle) - Тесты:
internal/bus/bus_test.go(success / inbound full / outbound full / recovers when reader / SessionKey override),internal/channels/manager_test.go(coalesce без re-publish, AllOurs, NoWebSocket),internal/store/actor_pending_test.go(FIFO, limit, empty key)
Changed
bus.PublishInbound/PublishOutboundбольше не делают silent-drop черезselect-default. Используетсяselectсtime.NewTimer(PublishTimeout)(5s по умолчанию). При таймауте —slog.Error, метрикаBusInboundDropped/BusOutboundDropped, возвратbus.ErrBusFull. Сигнатура изменилась сfunc(msg)наfunc(msg) error- Все callers
PublishInbound/PublishOutboundадаптированы: chat handler возвращает 503, email poller логирует и пропускает, base channel логирует,MessageToolвозвращает «bus overloaded» в LLM,ProcessDirectпробрасывает ошибку наружу actorChanCapувеличен с 32 до 128. При действительном переполненииrouteToActorсериализуетbus.InboundMessageв JSON и сохраняет вactor_pending_msg(вместоslog.Warn("dropping"))SessionActor.runподгружает spillover-сообщения при старте (после возможного рестарта процесса) и после каждой обработки (drainPending). Реинжект пакетами поpendingDrainBatch=32, FIFO поidChannelManager.coalesceStreamDeltasбольше не публикует «не наше» сообщение обратно вbus.Outbound— теперь сохраняет вm.pendingMsgподpendingMu.dispatchOutboundсначала проверяетpendingMsg, потом канал. Это устраняет потенциальный double-drop под нагрузкойChannelManager.forwardSystemNotificationпомимоsession_updatedтеперь рассылаетsystem_messageс Content для cron/heartbeat outbound. UI получает текст в WS-уведомлении даже при отсутствии открытого чата с этой сессией
Fixed
- Work §1.2/§3.1/§4.1 P0.1: silent-drop сообщений в шине под нагрузкой. Теперь caller знает, что сообщение не доставлено
- Work P0.3 / Bug B2.1: cron/heartbeat ответ агента не доходил до пользователя — теперь
forwardSystemNotificationретранслирует Content в WS какsystem_message - Work §1.2: dropping message at actor.ch full — заменено на persistent spillover в БД с автоматическим drain
- Work §1.2 (хвост): coalesceStreamDeltas могла re-publish-нуть в полную шину и потерять сообщение