Aller au contenu
Tous les articles

Filetable· Article 1 sur 3

Des files et des priorités : orchestrer des milliers de documents avec Temporal

Un document traverse une dizaine d'étapes d'OCR, d'IA et de SQL. Le vrai défi n'est pas de les enchaîner, c'est de décider qui passe en premier.

7 min de lectureRead in English

Quand on dépose une facture dans Filetable, elle traverse une série d'étapes : lecture du PDF, choix de la bonne table, extraction de chaque champ, liens vers les fournisseurs ou les commandes, rangement dans un dossier. Certaines prennent un dixième de seconde, d'autres deux minutes. Et il en arrive parfois des centaines d'un coup.

Pourquoi Temporal

Un traitement de ce genre a trois ennemis : les services externes qui tombent, les serveurs qui redémarrent, et le temps qui passe. On peut tout construire à la main, avec une file de messages, des statuts en base et des tâches planifiées pour rattraper ce qui s'est perdu. On finit alors par réécrire, en moins bien, ce que fait déjà Temporal.

Temporal est une plateforme open source d'exécution durable : elle garantit qu'un code va jusqu'au bout, quelles que soient les pannes. Conçue par les créateurs de Cadence, le moteur de workflows d'Uber, elle fait tourner aujourd'hui, selon son site, des produits d'OpenAI, de Replit ou de Cursor. On écrit le workflow comme du code ordinaire, étape après étape, et Temporal enregistre le résultat de chacune. Si un worker s'arrête en plein milieu, un autre reprend exactement là où il en était : rien n'est refait, rien n'est perdu. Les reprises, les délais et les attentes de plusieurs jours deviennent des lignes de code, plus de l'infrastructure.

Temporal

Exécution durable

Le worker A s'arrête en pleine extraction. Temporal a gardé le résultat des deux premières étapes : le worker B reprend à l'extraction, sans rien refaire.

Temporal existe en service managé, Temporal Cloud, facturé à l'usage. Mais le serveur est open source, sous licence MIT : Filetable le fait donc tourner lui-même, dans son cluster, à côté de l'application et de la base. Les données des workflows restent chez nous, aucune étape ne paie un aller-retour vers une autre région, et la facture ne dépend pas du nombre d'étapes exécutées. La contrepartie : c'est à nous de l'exploiter, de le mettre à jour et de le surveiller. J'en parle plus largement dans Lancer vite, puis tenir.

Chaque document a donc son workflow, et chaque étape est une activité : un morceau de travail que Temporal confie à un worker, relance s'il échoue, et dont il garde le résultat.

TemporalUn workflow par document
OCRlecture OCRIAappel au modèleSQLécriture SQL
  1. Lecture du documentOCR
  2. Choix de la tableIA
  3. Extraction des champsIA
  4. La ligne apparaîtSQL
  5. Relations × NIASQL
  6. FinalisationSQL
  7. Rangement en dossierIA
  8. « Terminé »SQL
Le parcours d'un document. Chaque étape est une activité, envoyée dans la file qui correspond à son travail.

Le défi. Ces étapes n'ont rien en commun. Un appel au modèle d'IA peut durer deux minutes ; écrire « Terminé » sur une ligne prend une fraction de seconde. Quand cinquante documents arrivent ensemble, la petite écriture attend derrière les gros appels, et l'utilisateur regarde tourner un document déjà fini.

La priorité ne suffit pas

Temporal sait prioriser : dans une file, une tâche urgente passe devant les autres. Mais la priorité ne fait qu'ordonner l'attente. Elle ne libère jamais un worker déjà occupé par un appel de deux minutes : si tous les slots sont pris, l'écriture urgente attend quand même.

La réponse est ailleurs : une file par nature de travail, chacune avec ses propres slots. Les écritures courtes ne font plus jamais la queue derrière l'IA, et chaque file se dimensionne selon ce qu'elle coûte vraiment.

Temporal

Une file par nature de travail

attente → slots
file rapidedes écritures courtes, attendues
P3rattrapageP2nouvelle ligneP1« Terminé »
file relationsune cellule à la fois
P3cellules × NP1à l'écran
file IAle travail lourd : lecture, modèle
P5nettoyageP3extractionP3lectureP2rangement
OCRlecture OCRIAappel au modèleSQLécriture SQL
Chaque file a ses propres slots. Dans une file, la priorité est stricte : P1 passe avant P2. Mais elle n'ordonne que l'attente ; elle ne libère jamais un slot occupé.

Mesuré sur des lots réels, avant et après :

Avant → après des files séparées

> 2 min
0,1 s

attente pour écrire « Terminé », une seule ligne

45 s
16 s

attente médiane avant l'extraction

Mesuré sur des lots réels de quelques dizaines de documents. Les écritures courtes pesaient moins de 1 % du temps de travail, mais attendaient derrière des appels au modèle de deux minutes.

Équitable entre clients

Dans une même file, un client qui dépose 500 factures ne doit pas faire attendre celui qui en dépose une. Temporal sait répartir les tâches par clé d'équité : chaque workflow porte celle de son espace de travail, pondérée par son plan. Un client seul profite de toute la capacité ; à plusieurs, chacun avance à son rythme.

Ordre de passage

client Aclient B
Même poidsABABABABABAB
Poids 1 contre 3BBBABBBABBBA
B seulBBBBBBBBBBBB
Dans une même priorité, les tâches sont réparties entre clients selon leur poids, ici leur plan. Un client seul profite de toute la capacité, et personne n'est jamais sauté.

Attendre sans bloquer

Quand le fournisseur d'IA sature, il refuse les appels, parfois pendant vingt minutes. Ce n'est pas la faute du document : il faut attendre, puis réessayer. Mais où on attend change tout. Une activité qui dort garde son slot pour rien ; un timer de workflow, lui, ne coûte rien, et survit même à un redémarrage.

Fournisseur IA saturé

essaislot bloqué pour rienslot libre
Une activité qui dort1′2′3′4′5′
Un timer du workflowTemporal1′2′3′4′5′
Le fournisseur refuse les appels pendant de longues minutes. Le workflow attend 1, 2, 3, 4 puis 5 minutes entre deux essais : un timer ne tient aucun slot, alors qu'une activité qui dort garderait le sien tout ce temps.

Ce que j'en retiens

  • L'exécution durable change la façon d'écrire du back-end. Les reprises et les attentes deviennent du code lisible.
  • La priorité ordonne, elle ne libère pas. Séparer les files selon la durée du travail.
  • Mesurer avant de régler. Une étape qui pèse moins de 1 % du temps peut quand même faire attendre l'utilisateur deux minutes.
  • Une attente vit dans le workflow, jamais dans une activité qui garde sa place.