feat: cola de jobs asincrona basada en SQLite (issue 0013)
Implementa el subsistema completo de background jobs para apps Go en el dominio infra. 9 funciones + 3 tipos + 17 tests, todos pasando. - Tipos: Job (product), JobQueue (product), JobStatus (sum) con JobHandler, EnqueueOption y WorkerOption usando functional options pattern - job_queue_create: CREATE TABLE + indices + WAL mode - job_enqueue: INSERT con UUID (github.com/google/uuid), WithPriority/WithScheduledAt/WithMaxAttempts - job_dequeue: SELECT+UPDATE atomico en transaccion exclusiva, filtro por jobTypes - job_complete / job_fail: transiciones de estado; fail → dead cuando attempts >= max_attempts - job_status_summary: pura, formatea conteo de jobs por estado - job_worker: poll loop bloqueante, context-cancelable, graceful shutdown - job_worker_pool: N workers con golang.org/x/sync/errgroup - job_cleanup: DELETE jobs terminales mas viejos que olderThan Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: job
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
algebraic: product
|
||||
definition: |
|
||||
type Job struct {
|
||||
ID string
|
||||
Type string
|
||||
Payload string
|
||||
Status JobStatus
|
||||
Priority int
|
||||
Attempts int
|
||||
MaxAttempts int
|
||||
ScheduledAt time.Time
|
||||
StartedAt *time.Time
|
||||
CompletedAt *time.Time
|
||||
Result *string
|
||||
Error *string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
description: "Unidad de trabajo asincrono almacenada en SQLite. Payload es un JSON string. Status evoluciona de pending a running y luego a completed, failed o dead."
|
||||
tags: [job, queue, async, background, sqlite, infra]
|
||||
uses_types: [job_status_go_infra]
|
||||
file_path: "functions/infra/job_queue_types.go"
|
||||
---
|
||||
|
||||
## Notas
|
||||
|
||||
Tipo producto. Los campos `StartedAt`, `CompletedAt`, `Result` y `Error` son punteros — son nil hasta que el job alcanza el estado correspondiente. `Payload` es siempre un JSON string (minimo "{}").
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: job_queue
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
algebraic: product
|
||||
definition: |
|
||||
type JobQueue struct {
|
||||
DB *sql.DB
|
||||
TableName string
|
||||
}
|
||||
description: "Handle para una cola de jobs SQLite. Wrappea un *sql.DB y el nombre de la tabla de jobs. Se crea con JobQueueCreate."
|
||||
tags: [job, queue, sqlite, infra, async]
|
||||
uses_types: []
|
||||
file_path: "functions/infra/job_queue_types.go"
|
||||
---
|
||||
|
||||
## Notas
|
||||
|
||||
Tipo producto minimo — todas las funciones del subsistema de jobs lo reciben como primer argumento. TableName permite tener multiples colas en la misma DB. Se crea con `JobQueueCreate`.
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: job_status
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
algebraic: sum
|
||||
definition: |
|
||||
type JobStatus string
|
||||
|
||||
const (
|
||||
JobStatusPending JobStatus = "pending"
|
||||
JobStatusRunning JobStatus = "running"
|
||||
JobStatusCompleted JobStatus = "completed"
|
||||
JobStatusFailed JobStatus = "failed"
|
||||
JobStatusDead JobStatus = "dead"
|
||||
)
|
||||
description: "Estado del ciclo de vida de un job. Tipo suma con cinco variantes: pending, running, completed, failed, dead."
|
||||
tags: [job, status, queue, async, infra]
|
||||
uses_types: []
|
||||
file_path: "functions/infra/job_queue_types.go"
|
||||
---
|
||||
|
||||
## Notas
|
||||
|
||||
Tipo suma. Ciclo de vida normal: pending → running → completed. En error: pending → running → failed (reintentos posibles) → dead (sin mas intentos). Un job con `attempts >= max_attempts` pasa directamente a dead.
|
||||
Reference in New Issue
Block a user