← Voltar a studyAI — Documentação do Projeto

⏳ Jobs Assíncronos

studyAI — Documentação do Projeto

Apresentação

Jobs Assíncronos — studyAI

Decisões operacionais para workers, retry, progress e failure handling.


Índice

  1. Worker framework
  2. Tipos de jobs
  3. Retry e failure strategy
  4. Progress updates
  5. Tabela jobs (operacional)

Diagrama: ciclo de vida de jobs

A carregar diagrama…

Retry e backoff

A carregar diagrama…

Worker framework

Decisão: Celery + Redis

OpçãoPrósContras
Celery + RedisMaduro, retry built-in, escalável, usado em produçãoMais setup
RQMais simples que CeleryMenos features
Background tasks (FastAPI)Zero dependênciasNão persiste, não escala, perde jobs ao restart
Inngest / Trigger.devManaged, observabilityCusto, vendor lock

Escolha: Celery + Redis.

Rationale:

  • Retry, dead-letter, rate limiting nativos
  • Escala com workers
  • Redis já usado para rate limit e cache
  • Fase 0/MVP: pode começar com BackgroundTasks do FastAPI para ingestão simples; migrar para Celery na Fase 1

MVP fallback: Background tasks inline para ingestão (1 worker). Sem fila persistente. Adequado para validar fluxo antes de Celery.


Tipos de jobs

TipoTriggerDuraçãoProgress
ingest_fileUpload de ficheiro10s–2min0→parse, 50→chunk, 100→done
reindex_projectPOST /index1–10minPor ficheiro
generate_contentPOST /generate2–10minPor secção (0–80), questions (80–100)

Retry e failure strategy

Retry

  • Backoff: Exponencial: 1min, 5min, 15min, 1h
  • Max retries: 5 (ingest), 3 (generate)
  • Retry quando: Erro de rede, timeout LLM, rate limit 429
  • Não retry: Erro de validação, ficheiro corrompido

Dead-letter / failure

  • Após max retries: Job marcado failed, error preenchido
  • Dead-letter queue: Opcional. Celery pode guardar em Redis ou log. Para MVP: só marcar failed em DB
  • Notificação: Log estruturado. Futuro: alerta se taxa de falha > X%
  • Recovery manual: Endpoint POST /jobs/:id/retry para admin re-disparar

Ingest específico

  • files.retry_count: Incrementar a cada tentativa
  • files.last_error: Guardar última mensagem
  • files.status: error após max retries
  • Cron opcional: Job que retenta files com status=error e retry_count < 5

Progress updates

Estratégia: Polling + SSE opcional

MétodoUsoQuando
PollingGET /jobs/:idDefault. Frontend faz poll a cada 2–5s
SSEGET /jobs/:id/streamOpcional. Conexão persistente, eventos em tempo real

Decisão: Implementar polling primeiro (GET /jobs/:id). SSE como melhoria futura se UX exigir.

Formato do progress (jobs.progress, jobs.result):

{
  "progress": 45,
  "message": "A escrever secção 2 de 5...",
  "current_section": 2,
  "total_sections": 5,
  "document_id": "uuid"  // quando criado
}

Tabela jobs (operacional)

ColunaTipoUso
idUUIDPK
project_idUUIDFK
typeVARCHARingest_file, reindex_project, generate_content
statusVARCHARpending, running, completed, failed
progressINTEGER0–100
messageTEXTMensagem humana ("A escrever secção 2...")
payloadJSONBInput do job (file_id, topic, etc.)
resultJSONBOutput (document_id, etc.)
errorTEXTMensagem de erro se failed
retry_countINTEGERTentativas feitas
started_atTIMESTAMPTZQuando começou a correr
completed_atTIMESTAMPTZQuando terminou
created_atTIMESTAMPTZ
updated_atTIMESTAMPTZ

Celery: task_id (opcional) para correlacionar com Celery result backend.

Zona de prática

Sem perguntas. Clica em Editar para adicionar.