Travaux et file d'attente
@bext-stack/framework/jobs est la couche ergonomique sur la file d'attente du SDK de bext — les tâches ShouldQueue de Laravel + Job::dispatch(), dans TypeScript. Déclarez les tâches (nom → type de charge utile + gestionnaire), dispatch les à partir d'un rendu ou d'une action, et un travailleur process met les enveloppes en file d'attente, les acheminant vers le gestionnaire droit avec les tentatives automatiques.
Quand l'utiliser#
- Supprimez le travail lent de la demande (envoyer un e-mail, redimensionner une image, facturer une carte).
- Tout ce que vous voulez, réessayé en cas d'échec passager.
- Mise en file d'attente typée + gestionnaire typé, afin que les charges utiles ne puissent pas dériver.
Déclaration et expédition#
import { createJobs } from "@bext-stack/framework/jobs";
const jobs = createJobs({
appId: "my-site", // → pushes to the SDK queue over loopback
jobs: {
sendInvoice: { handler: async (p: { orderId: string }) => { /* … */ } },
chargeCard: { maxAttempts: 3, handler: async (p: { amount: number }) => { /* may throw → retried */ } },
},
});
// enqueue from a render / action — typed payload, returns the queue job id:
await jobs.dispatch("sendInvoice", { orderId: "o1" });
await jobs.dispatch("chargeCard", { amount: 4200 }, { delaySecs: 30 });
Traitement#
Un travailleur (par exemple, un travailleur de tâche bext) retire les enveloppes de la file d'attente et les traite chacune - process est acheminé vers le gestionnaire et, en cas d'échec, **est remis en file d'attente avec
attempt + 1 **tant que les tentatives restent :
// for each envelope pulled from the queue:
const result = await jobs.process(envelope);
// → { job: "chargeCard", ok: false, attempt: 1, retried: true, error: "gateway timeout" }
// → …later… { job: "chargeCard", ok: true, attempt: 2 }
process ne lance jamais — il renvoie un JobResult ( ok, attempt, retried?,
error? ), la boucle de travail reste donc simple. maxAttempts (par défaut 1) limite les tentatives.
Transport enfichable (et tests)#
La file d'attente est un Dispatcher. La valeur par défaut est envoyée à la file d'attente du SDK ; injectez-en un pour des tests ou un flux autonome :
import { memoryDispatcher } from "@bext-stack/framework/jobs";
const disp = memoryDispatcher();
const jobs = createJobs({ jobs: { … }, dispatcher: disp });
disp.bind(jobs);
await jobs.dispatch("sendInvoice", { orderId: "o1" });
const results = await disp.drain(); // runs every queued envelope through process()
Essayez-le#
Le démo d'emplois en direct distribue trois tâches et les traite en une seule requête (en mémoire) : l'une échoue puis réussit lors d'une nouvelle tentative. Source dans sites/demo/src/app/examples/jobs/page.tsx.
Voir aussi#
- Tâches en arrière-plan / Planificateur de tâches — la file d'attente du SDK + les travailleurs en dessous.
- Flux durables — flux de travail durables et en plusieurs étapes.
- Notifications — une charge utile de tâche courante.
- Boîte à outils de candidature — le reste de la couche d'application TypeScript.