Queue Workers

La queue du SDK bext est une file de push au moins une fois. Vous mettez des payloads en file (voir SDK → Queue) et enregistrez un push-worker : un handler HTTP auquel le dispatcher envoie chaque message par requête POST. Elle s'atteint via le SDK loopback à http://127.0.0.1/__bext/sdk/queue/*, authentifiée par l'en-tête X-Bext-App-Id (voir Vue d'ensemble du SDK).

Enregistrer un worker

POST http://127.0.0.1/__bext/sdk/queue/worker/register
X-Bext-App-Id: <app-id>
Content-Type: application/json

Champs du corps :

Champ Requis Notes
queue oui Nom de la file à consommer
handler_url oui L'URL du vhost public de votre application pour cette file
concurrency non Nombre maximal de livraisons en cours
visibility_timeout_secs non Durée pendant laquelle une livraison est retenue avant d'être relancée
max_attempts non Nombre de tentatives avant qu'un message ne parte en lettre morte

Enregistrez handler_url comme l'URL publique de l'application, pas un chemin loopback — le dispatcher l'appelle comme n'importe quel client HTTP :

await fetch("http://127.0.0.1/__bext/sdk/queue/worker/register", {
  method: "POST",
  headers: { "X-Bext-App-Id": "<app-id>", "content-type": "application/json" },
  body: JSON.stringify({
    queue: "emails",
    handler_url: "https://<app>.inklura.fr/api/queue/emails",
    concurrency: 4,
    max_attempts: 5,
  }),
});

Le contrat du handler

À chaque livraison, le dispatcher envoie une enveloppe JSON par requête POST à votre handler_url :

{ "id": "<message-id>", "queue": "emails", "payload": { }, "attempts": 1 }

Le statut HTTP de votre handler décide de l'issue :

Statut de réponse Issue
2xx Ack — le message est terminé et supprimé
408, 429, 5xx Relance — relivré plus tard (jusqu'à max_attempts)
tout autre 4xx Lettre morte — déplacé vers la file de lettres mortes, non relancé
// src/app/api/queue/emails/route.ts
export async function POST(req: Request) {
  const { id, payload, attempts } = await req.json();
  try {
    await sendEmail(payload);
    return new Response("ok");                 // 2xx → ack
  } catch (e) {
    if (isTransient(e)) return new Response("retry", { status: 503 }); // 5xx → relance
    return new Response("bad payload", { status: 400 });               // 4xx → lettre morte
  }
}
Attention

La livraison est au moins une fois. Un message peut arriver plus d'une fois (un 2xx qui n'a jamais atteint le dispatcher, une relivraison après un délai de visibilité). Rendez les handlers idempotents — indexez les effets de bord sur l'id du message.

Pas de stockage de résultat — ajoutez un enregistrement de job durable

La queue est en fire-and-forget sans stockage de résultat. Une fois un message acquitté, il disparaît ; il n'existe aucun endroit intégré pour lire « le job X a-t-il réussi, qu'a-t-il renvoyé ». Si vous avez besoin d'un statut ou d'un résultat, écrivez votre propre enregistrement durable — l'endroit idiomatique est le KV sous une clé job:<id>.

// à la mise en file
await sdk.kv.set(`job:${id}`, { status: "queued", createdAt: Date.now() });

// dans le handler
await sdk.kv.set(`job:${id}`, { status: "running" });
// …travail…
await sdk.kv.set(`job:${id}`, { status: "done", result });

Opérations de lettre morte

Les messages qui épuisent max_attempts ou renvoient un 4xx non relançable atterrissent dans la file de lettres mortes. Gérez-les via le SDK :

Méthode Chemin Objet
POST /__bext/sdk/queue/dead/list Lister les messages en lettre morte
POST /__bext/sdk/queue/dead/retry Remettre en file les messages en lettre morte
POST /__bext/sdk/queue/dead/purge Supprimer les messages en lettre morte

Connexe : files BullMQ du company-manager

La queue décrite ici est la queue du SDK bext que possède une application PRISM. Séparément, le backend Next.js du company-manager exécute ses propres files BullMQ (Redis) déclarées dans un QUEUE_REGISTRYwebhook, webhook-retry, email-*, seo-*, social-*, woocommerce, prestashop, et les files d'automatisation workflow-*. Elles sont internes à la plateforme et ne sont pas enregistrées via le SDK ; voir Vue d'ensemble des événements et Webhooks entrants (les événements entrants alimentent la file webhook).

Voir aussi