| name | async-discipline |
| description | Async-дисциплина проекта: весь I/O через await, никаких requests/time.sleep, синхронные либы через asyncio.to_thread, общие клиенты. |
Skill: async-discipline
Правила работы с асинхронностью. Источник истины — _docs/instructions.md §4.
Когда использовать
- Пишешь handler, tool, сервис или агентный цикл, где есть I/O (HTTP, файлы, Telegram API,
sqlite-vec, Ollama).
- Интегрируешь синхронную библиотеку (
sqlite3, ddgs).
- Создаёшь клиент внешнего сервиса.
Алгоритм
- Любой I/O — только через
await. В hot path не должно быть блокирующих вызовов.
- Не используй
requests, time.sleep, блокирующие SDK. Разрешено: httpx.AsyncClient, ollama.AsyncClient, aiofiles (если нужно).
- Синхронную библиотеку оборачивай в
asyncio.to_thread(...) (например, sqlite3, ddgs).
- Не создавай новый event loop внутри handlers/tools — всё работает в loop'е, запущенном aiogram.
- Общие клиенты (HTTP, Ollama, SQLite-соединение) создавай один раз на приложение и закрывай при shutdown. В
__init__ tool'а — никаких сетевых вызовов, только сохранение зависимостей.
- Метод
run у tool — всегда async, даже если работа синхронная (единый контракт).
Пример
Синхронный поиск через ddgs внутри async-tool:
results = await asyncio.to_thread(lambda: DDGS().text(query, max_results=top_k))
Чего избегать
requests.get(...), time.sleep(...), open(...).read() в hot path event loop'а.
asyncio.run(...) / new_event_loop() внутри handlers и tools.
- Создания нового HTTP/Ollama-клиента на каждый запрос вместо переиспользования общего.