Files
ss-tools/specs/032-translate-requests-httpx/data-model.md
busya bc32dd65ef 032: mark all tasks [x] — feature complete
Updated status in spec.md, plan.md, tasks.md, research.md,
data-model.md, ux_reference.md, quickstart.md.
All 72 tasks completed. 34/34 tests passing.
2026-06-04 21:09:14 +03:00

7.8 KiB
Raw Blame History

Data Model: Async Backend Refactoring

Feature: 032-translate-requests-httpx Date: 2026-06-04 Status: Implemented

Overview

Рефакторинг не добавляет новых бизнес-таблиц (SQLAlchemy models) и не меняет публичные request/response Pydantic-схемы. Добавляются транспортные/runtime-сущности (SupersetClientRegistry, run_blocking, bounded executors) и расширяется конфигурация окружений (EnvironmentConfig) и приложения (AppAsyncRuntimeConfig). Требование миграции БД зависит от формата хранения EnvironmentConfig: если JSON/Pydantic blob — defaults через Field(default=...) достаточны; если SQLколонки — нужна Alembic-миграция.

1. Changed Entities (Transport Layer)

AsyncAPIClient (replaces APIClient)

Attribute Type Change
session requests.Sessionhttpx.AsyncClient Замена sync клиента на async
base_url str Без изменений
csrf_token str Без изменений (кешируется)
semaphore NEW asyncio.Semaphore Ограничение конкурентных соединений
timeout NEW httpx.Timeout Настраиваемый таймаут (default: 30s)

Lifecycle: Клиент создаётся через async with AsyncAPIClient(env_config) as client: — контекстный менеджер управляет жизненным циклом httpx.AsyncClient (открытие/закрытие connection pool).

SupersetClient (merged sync + async)

Attribute Type Change
network APIClientAsyncAPIClient Замена sync на async
All mixin methods defasync def Все 13 миксинов становятся async

Methods (typical signature change):

# Before (sync)
def get_dashboards(self, query=None) -> tuple[int, list[dict]]: ...

# After (async)
async def get_dashboards(self, query=None) -> tuple[int, list[dict]]: ...

SupersetSqlLabExecutor

Attribute Type Change
_client SupersetClient (sync) Замена на async
execute_sql() defasync def Асинхронный HTTP + поллинг
poll_execution_status() defasync def time.sleepasyncio.sleep
max_polls int (60) Без изменений
poll_interval_seconds float (2.0) Без изменений

TaskManager

Attribute Type Change
executor ThreadPoolExecutor Удалён
_tasks dict[str, asyncio.Task] NEW — словарь активных asyncio.Task
run_task() defasync def Запуск через asyncio.create_task
cancel_task() defasync def Отмена через task.cancel()

EventBus

Attribute Type Change
_queue queue.Queueasyncio.Queue Замена sync очереди на async
publish() defasync def put_nowaitawait put
subscribe() defasync def getawait get

LLM Client (unified)

Attribute Type Change
call_openai_compatible() defasync def Асинхронный HTTP
_do_http_request() requests.post + time.sleep httpx.AsyncClient.post + asyncio.sleep
timeout int (180) → httpx.Timeout(180) Настраиваемый таймаут

Notification Providers

Provider Method Change
SMTPProvider send() smtplib.SMTPaiosmtplib.SMTP
TelegramProvider send() requests.posthttpx.AsyncClient.post
SlackProvider send() requests.posthttpx.AsyncClient.post

2. New Entities

SupersetClientRegistry [C:4]

Синглтон-реестр долгоживущих асинхронных клиентов по env_id:

Attribute Type Description
_clients dict[str, _ClientSlot] env_id → slot с shared ресурсами
_ClientSlot.client httpx.AsyncClient Долгоживущий HTTP-клиент (connection pooling)
_ClientSlot.semaphore asyncio.Semaphore Глобальный perenv семафор (connection_pool_size)
_ClientSlot.auth_lock asyncio.Lock Защита конкурентного обновления CSRF/authтокенов

Lifecycle: Клиенты создаются при первом обращении к env_id, живут до shutdown. async with — только для тестов.

DB Threading Contract

SQLAlchemyсессии создаются, используются, коммитятся/откатываются и закрываются внутри одного workerпотока (через asyncio.to_thread(db_executor, ...)). Никакие ORMобъекты не пересекают границу потока без явного detach/serialization. DBадаптер владеет жизненным циклом сессии.

3. Configuration Parameters

Environment Config (per Superset instance — EnvironmentConfig)

{
  "connection_pool_size": 20,
  "connection_pool_timeout": 30,
  "request_timeout": 30,
  "llm_timeout": 120
}

App-Level Async Runtime Config (global — отдельная секция конфигурации приложения, не perenv)

{
  "db_executor_workers": 10,
  "file_executor_workers": 10,
  "git_executor_workers": 5,
  "graceful_shutdown_timeout": 30
}

Эти параметры добавляются в модель EnvironmentConfig (Pydantic) и хранятся в БД как часть конфигурации окружения.

3. Unchanged Entities

Следующие сущности не меняют свою структуру, только способ взаимодействия с внешними сервисами:

Entity Type Notes
TranslationJob SQLAlchemy Model Без изменений
TranslationPreviewSession SQLAlchemy Model Без изменений
TranslationPreviewRecord SQLAlchemy Model Без изменений
TranslationPreviewLanguage SQLAlchemy Model Без изменений
Dictionary SQLAlchemy Model Без изменений
LLMProvider SQLAlchemy Model Без изменений
EnvironmentConfig SQLAlchemy Model Добавлены pool-параметры (см. выше)
Все Pydantic request/response schemas Pydantic Без изменений (FR-018)
Все API routes (URL, method, status codes) FastAPI Router Без изменений
PluginBase.execute() contract ABC Уже async def, без изменений

4. Task State Transitions (Unchanged)

PENDING → RUNNING → COMPLETED
                  → FAILED
                  → CANCELLED

Переходы состояний не меняются. Меняется только механизм запуска: ThreadPoolExecutor.submit()asyncio.create_task().

5. WebSocket Message Format (Unchanged)

{
  "type": "log",
  "task_id": "uuid",
  "timestamp": "ISO-8601",
  "level": "INFO|WARNING|ERROR",
  "message": "...",
  "trace_id": "uuid"
}

Формат сообщений WebSocket не меняется. Меняется только транспорт отправки: queue.Queue + call_soon_threadsafeasyncio.Queue + await.