- chat.Router: ограниченный пул chatWorkers=4 воркеров + FIFO-очереди
per-user (userState/workerLoop/runUser). Порядок сообщений одного UserID
сохраняется; разные пользователи обрабатываются параллельно (до 4
одновременных LLM-вызовов), long-poll Telegram не блокируется чужим
аналитиком. Backpressure по jobs — только на перегруженного пользователя.
- app.FreeChat: sessions под sync.Mutex (защита от data race при параллельных
воркерах роутера).
- update: ResolveLatest проверяет наличие бинаря HEAD-пробой без скачивания
тела (fallback GET Range 0-0 при 405/501), сортировка версий по id убыв.;
один общий http.Client (keep-alive) вместо нового на каждый запрос.
- тесты: порядок/параллелизм per-user в router, HEAD-без-тела и фоллбэк на
версию без бинаря в update.
- память Serena: инварианты Router/update, примечания по форматированию на Windows.
Router теперь обрабатывает входящие в воркер-горутине (FIFO-очередь с
буфером 256) вместо синхронного вызова onUserMsg из long-poll цикла
канала. Долгий вызов аналитика (Decide) больше не блокирует приём
новых сообщений от Telegram: цикл getUpdates продолжает работать.
- router.go: NewRouter запускает processLoop; handleIncoming кладёт
событие в канал и возвращается; маршрутизация + pending по-прежнему
обновляются синхронно под мьютексом.
- router_test.go: fakeOnMsg стал потокобезопасным с ожиданием числа
входящих (wait), т.к. обработка теперь асинхронная.
Преимущества: интерфейс не замирает на время анализа; порядок входящих
сохраняется (FIFO). Ограничение: воркер один — при очень долгом аналитике
следующие сообщения ждут в очереди, но канал их продолжает принимать.