Logotipo de Aurabase
aurabasedocumentos
documentos›Edge Functions›Jobs, cron and the DLQ

Jobs, cron y la cola de mensajes fallidos

Cómo ejecutar un trabajo fuera de una solicitud: qué es un trabajo, cómo se reintenta, cómo crea cron trabajos y qué hacer con los trabajos que terminan inactivos.

9 min leer·Nivel intermedio·Revisado el 12 oct 2026
Este texto en inglés se generó automáticamente a partir del original en francés y aún no ha sido revisado.
Esta página fue traducida automáticamente. La versión en inglés es autorizada.
#
poner en cola

1. Poner en cola un trabajo

Un trabajo es una llamada en segundo plano a una función. Ponlo en cola desde un servidor con una clave service_role.

server/enqueue.tstypescript
import { createClient } from '@aurabase/aurabase-js'

const admin = createClient(process.env.AURA_URL!, process.env.AURA_SERVICE_ROLE_KEY!)

const { data: job, error } = await admin.functions.enqueueJob('send-report', {
  payload: { month: '2026-10' },
  delaySecs: 60,   // Espere 60 segundos antes del primer intento.
  maxAttempts: 3,  // el valor predeterminado
})
OpciónPredeterminadoSignificado
payloadnullJSON dado a la función como cuerpo de la solicitud
delaySecs0Segundos de espera antes del primer intento. El trabajo permanece pending hasta entonces.
maxAttempts3Número total de intentos, incluido el primero.

Lee un trabajo con getJob(id) o listJobs({ status, limit }) (limit está entre 1 y 500, el valor predeterminado es 50). El trabajo tiene un status, attempts, max_attempts, error y las fechas scheduled_at, started_at, completed_at.

Los trabajos son una herramienta del lado del servidor

enqueueJob, getJob y listJobs necesitan una clave service_role. Una clave pública recibe 403.

#
manejador

2. Qué recibe tu función

Un trabajo llama a tu función como cualquier otra solicitud, con tres diferencias que debes manejar:

parteValor
MétodoJOB (no POST)
Camino/jobs/<job id>
cuerpoEl trabajo es payload, como JSON
Encabezados de identidadNinguno: x-aura-role y x-aura-user-id están ausentes
aurabase/functions/send-report/index.tstypescript
Deno.serve(async (req) => {
  const jobId = new URL(req.url).pathname.split('/').pop()
  const { month } = await req.json()
  // …compilar y enviar el informe, utilizando jobId como clave de idempotencia
  return new Response('ok')
})

Una llamada real registrada {"method":"JOB","path":"/jobs/d443d541-…","role":null,"userId":null,"body":"{\"items\":[\"a\",\"b\"],\"order\":42}"}.

Un trabajo se ejecuta sin un usuario: no confíe en x-aura-user-id. Si el trabajo pertenece a un usuario, coloque la identificación del usuario en la carga útil.

#
Reintentos

3. Ciclo de vida y reintentos

statusestext
pending ──claimed──▶ running ──▶ completed
   ▲                    │
   └── after 5 s ◀── failed (attempts left)
                        └──▶ dead (no attempts left)
  • Un trabajo ejecuta al menos una vez. Puede ejecutarse dos veces si un trabajador se detiene mientras se está ejecutando, así que haga que la función sea idempotente.
  • Un intento fallido se vuelve a intentar después de un retraso fijo de 5 segundos, hasta que se alcanza maxAttempts. Entonces el trabajo es dead. El retraso y el recuento de intentos predeterminado son configuraciones de servicio (JOB_RETRY_DELAY_SECS, JOB_MAX_RETRIES).
  • El servicio reclama un trabajo que todavía es running después de su concesión (450 segundos de forma predeterminada).
  • Los trabajos terminados se conservan durante 14 días de forma predeterminada.
Un error HTTP de su función no es un fracaso

Un trabajo es completed tan pronto como su función responde, cualquiera que sea el código de estado. En una ejecución real, una función que devolvió 500 produjo un trabajo completed después de un intento y nunca se volvió a intentar.

Un trabajo falla y se vuelve a intentar solo cuando falla la llamada misma: la función no existe o está inactiva, el tiempo de ejecución es inalcanzable o la llamada agota el tiempo de espera. Si desea volver a intentarlo cuando su propio código detecte un error, ponga en cola un nuevo trabajo desde el controlador (con delaySecs para una pausa) en lugar de confiar en el código de estado.

En la misma ejecución real, un trabajo para una función que no existe pasó por esta secuencia: el intento 1 falló a los 3 s con Fonction 'ghost' introuvable, el intento 2 falló aproximadamente a los 9 s y el trabajo se convirtió en dead con attempts igual a max_attempts.

#
Recuperación

4. La cola de mensajes fallidos

Los trabajos inactivos permanecen en la cola y se pueden enumerar y volver a intentar. Estas rutas aún no tienen ningún método SDK: use HTTP con una clave service_role.

terminalbash
# enumerar trabajos muertos
curl "$AURA_URL/v1/functions/jobs/dlq" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# reintentar un trabajo
curl -X POST "$AURA_URL/v1/functions/jobs/$JOB_ID/retry" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# reintentar cada trabajo muerto (hasta 1000)
curl -X POST "$AURA_URL/v1/functions/jobs/dlq/requeue" -H "apikey: $AURA_SERVICE_ROLE_KEY"
# → {"datos":{"requeued":1},"meta":null}

Un reintento devuelve el trabajo a pending sin restablecer su contador de intentos, por lo que obtiene exactamente un intento más y regresa a dead si falla nuevamente. Corrija la causa (implemente la función que falta, por ejemplo) antes de volver a intentarlo.

#
Horario

5. Programar con cron

Una entrada cron no llama a la función en sí: cada vez que se activa, pone en cola un trabajo.

server/cron.tstypescript
await admin.functions.createCronJob('nightly-cleanup', '0 3 * * *', 'cleanup', {
  payload: { dryRun: false },
})

const { data: crons } = await admin.functions.listCronJobs()
await admin.functions.deleteCronJob('nightly-cleanup') // por NOMBRE, no por id
  • La programación tiene 5 campos (min hour day month weekday) o 6 campos (sec min hour day month weekday). Una programación de 5 campos tiene 0 segundos por delante: */1 * * * * se almacena como 0 */1 * * * *.
  • Alias como @daily se rechazan con un 400 que indica el formato esperado.
  • Los horarios están en UTC.
  • last_run y next_run son null hasta el primer disparo. En una ejecución real, una programación creada a las 15:40 se disparó a las 15:41:00 y luego mostró next_run 15:42:00.
  • La carga útil se congela cuando crea la entrada.
  • Eliminar un nombre desconocido devuelve 404. Eliminar una entrada cron también evita que se active.
  • El SDK no tiene getCronJob o updateCronJob: elimine la entrada y créela nuevamente.

Para trabajos puramente de base de datos, la extensión Postgres pg_cron evita el viaje de ida y vuelta a una función: consulte la página Cron.

Última actualización · 12 oct 2026