Logo Aurabase
aurabasedocuments
documents›Edge Functions›Jobs, cron and the DLQ

Emplois, cron et file d'attente de lettres mortes

Comment exécuter un travail en dehors d'une requête : qu'est-ce qu'un travail, comment il est réessayé, comment cron crée des travaux et que faire des travaux qui finissent par disparaître.

9 min de lecture·Niveau intermédiaire·Révisé le 12 oct. 2026
Ce texte anglais a été généré automatiquement à partir de l’original français et n’a pas encore été relu.
Cette page a été traduite automatiquement. La version anglaise fait foi.
#
Mettre en file d'attente

1. Mettre un travail en file d'attente

Un travail est un appel en arrière-plan à une fonction. Mettez-le en file d'attente à partir d'un serveur avec une clé 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,   // attendez 60 secondes avant la première tentative
  maxAttempts: 3,  // la valeur par défaut
})
OptionsPar défautSignification
payloadnullJSON donné à la fonction comme corps de la requête
delaySecs0Quelques secondes à attendre avant la première tentative. Le travail reste pending jusque-là.
maxAttempts3Nombre total de tentatives, la première incluse

Vous relisez un travail avec getJob(id) ou listJobs({ status, limit }) (limit est compris entre 1 et 500, 50 par défaut). Le travail comporte un status, attempts, max_attempts, error et les dates scheduled_at, started_at, completed_at.

Les tâches sont un outil côté serveur

enqueueJob, getJob et listJobs nécessitent une clé service_role. Une clé publique reçoit 403.

#
Gestionnaire

2. Ce que reçoit votre fonction

Un travail appelle votre fonction comme n'importe quelle autre requête, avec trois différences que vous devez gérer :

PartieValeur
MéthodeJOB (et non POST)
Chemin/jobs/<job id>
CorpsLe travail est payload, en JSON
En-têtes d'identitéAucun : x-aura-role et x-aura-user-id sont absents
aurabase/functions/send-report/index.tstypescript
Deno.serve(async (req) => {
  const jobId = new URL(req.url).pathname.split('/').pop()
  const { month } = await req.json()
  // …créer et envoyer le rapport, en utilisant jobId comme clé d'idempotence
  return new Response('ok')
})

Un véritable appel enregistré {"method":"JOB","path":"/jobs/d443d541-…","role":null,"userId":null,"body":"{\"items\":[\"a\",\"b\"],\"order\":42}"}.

Un travail s'exécute sans utilisateur : ne comptez pas sur x-aura-user-id. Si le travail appartient à un utilisateur, placez l'identifiant de l'utilisateur dans la charge utile.

#
Nouvelles tentatives

3. Cycle de vie et tentatives

statusestext
pending ──claimed──▶ running ──▶ completed
   ▲                    │
   └── after 5 s ◀── failed (attempts left)
                        └──▶ dead (no attempts left)
  • Un travail exécute au moins une fois. Il peut s'exécuter deux fois si un travailleur s'arrête pendant son exécution, rendez donc la fonction idempotente.
  • Une tentative échouée est réessayée après un délai fixe de 5 secondes, jusqu'à ce que maxAttempts soit atteint. Le travail est alors dead. Le délai et le nombre de tentatives par défaut sont des paramètres de service (JOB_RETRY_DELAY_SECS, JOB_MAX_RETRIES).
  • Une tâche qui est toujours running après son bail (450 secondes par défaut) est récupérée par le service.
  • Les travaux terminés sont conservés pendant 14 jours par défaut.
Une erreur HTTP de votre fonction n'est pas un échec

Un job est completed dès que votre fonction répond, quel que soit le code d'état. Lors d'une exécution réelle, une fonction qui renvoyait 500 a produit une tâche completed après une tentative et n'a jamais été réessayée.

Une tâche échoue et est réessayée uniquement lorsque l'appel lui-même échoue : la fonction n'existe pas ou est inactive, le runtime est inaccessible ou l'appel expire. Si vous souhaitez réessayer lorsque votre propre code détecte une erreur, mettez en file d'attente une nouvelle tâche à partir du gestionnaire (avec delaySecs pour une interruption) au lieu de vous fier au code d'état.

Dans la même exécution réelle, une tâche pour une fonction qui n'existe pas a suivi cette séquence : la tentative 1 a échoué à 3 s avec Fonction 'ghost' introuvable, la tentative 2 a échoué à environ 9 s et la tâche est devenue dead avec attempts égal à max_attempts.

#
Récupération

4. La file d'attente des lettres mortes

Les travaux morts restent dans la file d'attente et peuvent être répertoriés et réessayés. Ces routes n'ont pas encore de méthode SDK : utilisez HTTP avec une clé service_role.

terminalbash
# lister les emplois morts
curl "$AURA_URL/v1/functions/jobs/dlq" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# réessayer une tâche
curl -X POST "$AURA_URL/v1/functions/jobs/$JOB_ID/retry" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# réessayez chaque travail mort (jusqu'à 1000)
curl -X POST "$AURA_URL/v1/functions/jobs/dlq/requeue" -H "apikey: $AURA_SERVICE_ROLE_KEY"
# → {"data":{"requeued":1},"meta":null}

Une nouvelle tentative remet le travail à pending sans réinitialiser son compteur de tentatives, il obtient donc exactement une tentative supplémentaire et revient à dead s'il échoue à nouveau. Corrigez la cause (déployez la fonction manquante, par exemple) avant de réessayer.

#
Calendrier

5. Planifiez avec cron

Une entrée cron n'appelle pas la fonction elle-même : chaque fois qu'elle se déclenche, elle met une tâche en file d'attente.

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') // par NOM, pas par identifiant
  • Le planning comporte 5 champs (min hour day month weekday) ou 6 champs (sec min hour day month weekday). Un programme à 5 champs obtient 0 secondes devant : */1 * * * * est stocké sous 0 */1 * * * *.
  • Les alias tels que @daily sont refusés avec un 400 indiquant le format attendu.
  • Les heures sont en UTC.
  • last_run et next_run sont null jusqu'au premier tir. Dans une exécution réelle, un programme créé à 15h40 s'est déclenché à 15h41:00, puis a affiché next_run 15:42:00.
  • La charge utile est gelée lorsque vous créez l'entrée.
  • La suppression d'un nom inconnu renvoie 404. La suppression d'une entrée cron l'empêche également de se déclencher.
  • Le SDK n'a pas de getCronJob ou updateCronJob: supprimez l'entrée et créez-la à nouveau.

Pour un travail purement base de données, l'extension Postgres pg_cron évite l'aller-retour vers une fonction : voir la page Cron.

Dernière mise à jour · 12 oct. 2026