88 lines
4.2 KiB
Markdown
88 lines
4.2 KiB
Markdown
# Брейншторм: Микросервисные паттерны
|
||
Дата: 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ч — начинаем с текущего момента
|
||
```
|