# Брейншторм: Микросервисные паттерны Дата: 2026-02-21 ## Контекст Team Board = микросервисная архитектура: Tracker (ядро), Picogent (агенты), Bridges (Telegram, OpenClaw), Web Client, BFF. ## Принятые паттерны ### ✅ Event Bus (Redis Streams) — КЛЮЧЕВОЕ Redis Streams как шина событий между Tracker и потребителями. **Проблема:** WS-событие теряется если клиент offline. При reconnect — пропущенные сообщения потеряны. **Решение:** Tracker пишет события в Redis Stream → потребители (agents, bridges) читают из stream. Если потребитель был offline → при reconnect читает с последнего обработанного offset. **Плюсы:** - Persistent queue — события не теряются - Consumer groups — несколько потребителей одного потока - Replay — можно перечитать историю - Redis у нас уже есть (порт 6380) **Статус:** нужно продумать детали (формат событий, consumer groups, retention policy). ### ✅ Saga Pattern (компенсации) Каждый шаг агента имеет компенсацию при сбое. Пример: 1. `take_task(42)` → задача in_progress 2. Агент работает... 3. Агент упал (heartbeat timeout) 4. Компенсация: задача → todo, комментарий "Агент упал, задача возвращена" ### ✅ Idempotency Каждое сообщение/событие имеет уникальный ID. Повторная доставка с тем же ID → игнорируется. Критично для reliable delivery через Event Bus. ### ✅ Centralized Logging Все сервисы: structured JSON logging (Pino для Node.js, structlog для Python). Единый формат → возможность агрегации. ### ✅ Circuit Breaker Exponential backoff при недоступности Tracker. Picogent уже реализует (1s → 2s → 4s → ... → 30s cap). Event Bus частично решает: если Tracker упал, события копятся в Redis. ## Отклонённые ### ❌ Service Discovery Один Tracker — overkill. ### ❌ API Gateway (BFF для всех) Бессмысленно отдельный BFF если все через него. BFF остаётся только для Web Client. ### ❌ Health Check / Readiness Probe Агенты должны быть доступны по IP:port — слишком сложно. Heartbeat через WS достаточен. ## На подумать ### ✅ Event Bus: Redis Streams (решение) **Выбор: Redis Streams** (не RabbitMQ — тот не хранит историю). **Роль:** real-time доставка + буфер при reconnect. НЕ хранилище истории (это PostgreSQL). **Retention:** ~24ч. Старые события — из PostgreSQL через REST API. ### ✅ Lazy Loading контекста (ключевое решение) Агент при подключении **НЕ грузит историю**. Как человек — зашёл и видит только новое. ``` 1. Subscribe на Redis Stream (real-time, с текущего момента) 2. GET /tasks?assignee=me # мои задачи 3. GET /project/{id}/docs # документация 4. Работает. Историю НЕ грузит. 5. Если нужен контекст → read_messages(limit=10) — пагинация назад ``` **Почему:** не засоряет контекст LLM, агент сам решает когда подгружать. **Prompt guideline:** "Если не хватает контекста — используй read_messages()" ### Reconnect ``` 1. XREAD STREAMS events {last_event_id} # пропущенные 2. Если last_event_id > 24ч — начинаем с текущего момента ```