veilletech.fr
5 nov. Feed du jour
#09 VERCEL Article

Workflow SDK : un start() idempotent, sans course

Votre identifiant métier est déjà votre clé d'idempotence.

Le start() du Workflow SDK de Vercel peut désormais admettre un run et réserver un hook en une seule étape atomique. Le jeton du hook, tiré de votre domaine (ID de commande, de facture), sert de clé d'idempotence : un doublon lève HookConflictError au lieu de démarrer un second run. Cela remplace le motif getHookByToken() puis start(), qui laissait une course.

2 min de lectureavancévidéo 1:17
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. Le mécanisme
  3. Les limites
  4. Comment s'y prendre
  5. À retenir

Ce qui se passe

Dans le Workflow SDK de Vercel, start() accepte maintenant une option experimental_hook : il admet le run et réserve un hook en une seule étape atomique. Un démarrage en double échoue proprement. L'ancien motif enchaînait getHookByToken() puis start() ; entre la recherche et le démarrage, une course documentée laissait deux requêtes simultanées lancer chacune un run (webhook rejoué, double clic).

Le mécanisme

Le jeton du hook est la clé d'idempotence, et il vient de votre domaine : un identifiant de commande, de facture, d'import ou de requête. Un seul run le possède. Un second start() avec le même jeton lève HookConflictError, qui porte le conflictingRunId du propriétaire, et ne devient jamais un run.

TypeScript
try {
  const run = await start(processOrder, [orderId, note], {
    experimental_hook: { token: `order:${orderId}` },
  });
  return Response.json({ runId: run.runId, started: true });
} catch (error) {
  if (!HookConflictError.is(error)) throw error;
  // Le doublon envoie sa charge au run qui possède déjà le jeton
  const hook = await resumeHook(`order:${orderId}`, { note });
  return Response.json({ runId: hook.runId, started: false });
}

Le hook réservé existe dès l'admission : resumeHook fonctionne avant que le run n'ait commencé à s'exécuter, et les charges arrivées trop tôt sont mises en tampon puis livrées dans l'ordre. Dans le workflow, createHook({ token }) avec le même jeton se lie au hook déjà réservé : aucun conflit possible, rien de nouveau enregistré, aucune étape ajoutée. Le jeton seul garantit l'idempotence : si le workflow n'ouvre jamais le hook, il n'aura servi que de clé, et le run se termine normalement.

Les limites

L'option porte le préfixe experimental_ : son interface peut encore changer. Pour qu'un doublon tardif soit aussi refusé, experimental_minRetention garde le jeton indisponible après la fin du run, durée comptée depuis le start().

Comment s'y prendre

  1. Passer à workflow 5.4.0.
  2. Remplacer vos paires getHookByToken() puis start() par un seul start() avec experimental_hook.
  3. Choisir le jeton dans votre domaine : un identifiant aléatoire ne reconnaîtrait pas le doublon.

Source : changelog Vercel, avec la documentation sur l'idempotence. Source en anglais.