orquestador/specs/WORKER.md

122 lines
7.2 KiB
Markdown

# Worker durable y consulta de ejecución — T10
El worker usa PostgreSQL como cola durable. `WORKER_ENABLED=true` activa polling,
reclamación, renovación y recuperación; false por defecto. Es independiente de
REQUEST_API_ENABLED y FLOW_ADMIN_ENABLED, pero siempre exige el runtime DB
restringido y Flyway separado. Puede desplegarse como proceso solo worker usando
la misma imagen. No se ha desplegado esta versión.
Defaults: 10 workers, lote máximo 10, polling 500 ms, lease 60 s y renovación cada
15 s. Variables WORKER_CONCURRENCY/BATCH/POLL_MS/LEASE_SECONDS/RENEW_SECONDS en
.env.example y compose.yaml. La renovación debe ser menor que la mitad del lease.
El scheduler reclama únicamente capacidad libre; no acumula una cola local de
trabajos ya reclamados que caduquen esperando un thread. Los executors locales
despachan trabajo; execution/action_execution conservan toda la evidencia durable.
## Protocolo y concurrencia
Un CTE con FOR UPDATE SKIP LOCKED reclama PENDING/RETRY_WAIT vencidos y RUNNING con
lease expirado. Orden next_attempt_at/created_at/id, límite de lote. En la misma
transacción incrementa attempts/fencing_token y fija owner/lease con clock_timestamp
de PostgreSQL. Se confirma antes de evaluar o invocar un adapter.
Renovar requiere RUNNING, executionId/requestId, owner y token exactos, y lease aún
vigente. Un lease vencido no revive por renovación. Reclamarlo aumenta el token;
el propietario anterior no puede cargar, iniciar/guardar checkpoints, fallar ni
confirmar el trabajo. Escrituras de checkpoint bloquean la ejecución y verifican
lease con tiempo DB al inicio y antes del commit. Finalización/fallo bloquean
solicitud y después ejecución; no hay transacciones abiertas mientras corre el adapter.
El worker carga estado/revisión aceptados y la definición por flow_id fijado.
Rechaza una solicitud modificada antes de llamar al adapter y vuelve a comprobar
estado, revisión, versión y lease al finalizar. accepted_revision es la revisión
posterior a aceptar T09. Un worker obsoleto que retorna después de otro no puede
sobrescribir el resultado, aunque el proveedor haya procesado su llamada.
## Acciones y checkpoints
WorkerActions es un registro de adapters confiable, consciente de versión, que
declara capability/schemas/effect y ejecuta la acción. ActionContext contiene inputs
resueltos, identidad mínima y clave externa estable `executionId:actionId`.
No se aceptan capacidades ni URLs del evento. NO_OP sigue prohibido fuera de simulación.
Antes de invocar se valida input y persiste checkpoint RUNNING, input_hash SHA-256,
clave externa, clasificación de efecto e intento. Al retornar, valida output y lo
guarda SUCCEEDED antes de avanzar. Tras recuperación, SUCCEEDED se reutiliza solo
si hash/clave/effect coinciden; no vuelve a ejecutar el adapter. Los mappings de
acciones posteriores usan los resultados recuperados. Cambio incompatible bloquea
con error de contrato y conciliación; nunca se usa silenciosamente un resultado ajeno.
V3 agrega action_execution.effect. Lo declara el adapter confiable, no el flujo.
Checkpoints anteriores a V3 se clasifican conservadoramente NON_IDEMPOTENT_WRITE;
no se inventa que eran seguros. V1/V2 no se alteran. Migración/rollback y permisos
se verifican contra PostgreSQL 9.6.2 en la base de pruebas.
Recuperación inicial:
- Acción READ_ONLY o IDEMPOTENT_WRITE en curso puede retomarse con misma clave y
hash, respetando maxAttempts del contrato de acción.
- NON_IDEMPOTENT_WRITE RUNNING o UNKNOWN no se repite: ejecución pasa a
RECONCILIATION_REQUIRED y la solicitud permanece bloqueada.
- Un fallo posterior a escrituras exitosas o pendientes tampoco libera la
solicitud como FAILED; se conserva para conciliación.
- Fallo de persistencia final deja RUNNING/checkpoints existentes para recuperación
por lease. Al reanudar no se repiten acciones ya SUCCEEDED.
T12 programa reintentos transitorios seguros con backoff/jitter y Retry-After
acotados. El checkpoint del intento, RETRY_WAIT y auditoría se confirman juntos;
no se pierden éxitos anteriores. Agotamiento seguro termina FAILED; escrituras
inciertas conservan el bloqueo para resolución administrativa. RECONCILIATION.md
documenta límites, evidencia, replay y autorización.
Los adapters T11 limitan sus timeouts y presupuesto de ejecución por debajo
del lease y respetar la idempotencia externa; el token local no evita duplicados
en el proveedor.
## Finalización
Tras las acciones, el evaluador puro T05 decide destino/outcome. Los updates se
calculan desde el snapshot original y resultados de acciones, se aplican sobre una
copia y se valida dataSchema y límite de 256 KiB antes de confirmar. JSON Pointer
admite objetos y posiciones existentes de arrays; no crea índices dispersos ni
interpreta append `-`. Padres de objeto ausentes se crean como objetos y el schema
final decide su validez. Nunca se actualiza identidad/ACL desde estos mappings.
Transacción final comprueba todos los checkpoints esperados SUCCEEDED y actualiza
data/estado/revisión de solicitud, resultado SUCCEEDED de execution y auditoría
TRANSITION_COMPLETED con transitionId, actionIds, hitPolicy y ruleIds. Cualquier
fallo revierte esos cambios juntos, conservando los checkpoints previos.
## Consulta y operación
GET /api/v1/executions/{id} ya implementado bajo REQUEST_API_ENABLED. Reutiliza
ResourceAccess y filtra owner/scope en SQL. Retorna ExecutionView con estado,
resultado de negocio permitido y código de error seguro; no devuelve inputs de
acciones, actor_snapshot, tokens, lease_owner ni respuesta cruda del proveedor.
Recurso ajeno/inexistente retorna 404. Location de T09 ya puede consultarse.
Apagado: detiene reclamación, conserva renovaciones durante hasta 20 s de drenaje,
interrumpe trabajos restantes y deja de renovar. Checkpoints/leases permiten la
recuperación. Un heartbeat que termina tarde no interrumpe otro trabajo que reutilice
el thread. Los adapters deben tener tiempo de espera finito; la interrupción no
garantiza cancelar un efecto externo, por eso se conserva la clasificación durable.
T11 incorpora adapters HTTP y verificación documental en el registro productivo.
Una acción sin contrato/ruta configurados falla con INTEGRATION_UNAVAILABLE.
Los catálogos predeterminados están vacíos. Configurar contratos y rutas antes de
habilitar integraciones; consultar INTEGRATIONS.md. NO_OP no puede ejecutarse.
## Evidencia y límites
WorkerIT usa PostgreSQL real/JWT local y adapters exclusivamente de prueba. Las
barreras verifican reclamantes concurrentes, SKIP LOCKED, fencing, retorno tardío,
renovación durante acción, checkpoints tras caída, clave externa estable, efecto
no seguro, rollback final, decisiones y autorización HTTP. SimulatedCrash abandona
el intento sin guardar resultado; se reconstruye el adapter de persistencia y se
recupera desde DB. No se anuncia una prueba de caída del proceso/JVM ni integración
real con proveedor. La idempotencia del proveedor se demuestra solo con un doble
explícito que deduplica por clave; T11/T16 comprobarán los contratos externos.
Ejecutar `mvnw.cmd clean verify -Pmigration-tests-external` con credenciales solo en
MIGRATION_TEST_DB_* y base orquestador_test. Sin ese perfil, verify necesita Docker
para Testcontainers. Los esquemas y roles temporales propios se eliminan al finalizar.