PD-21 — Spécification (révision clarifiée)¶
Statut : Révision suite audit d’ambiguïtés et de testabilité
Principe directeur : La spécification fait loi. Aucune hypothèse implicite. Toute règle est testable ou explicitement hors périmètre.
1. Objectif¶
Définir de manière non ambiguë, testable et auditable le comportement du système de traitement asynchrone de jobs utilisé par ProbatioVault (files de jobs), afin de garantir :
- la non‑interférence avec le flux principal (API synchrone),
- une sémantique d’exécution déterministe et vérifiable,
- une traçabilité consultable des états et événements,
- une sécurité explicite du backend de queue,
- une diagnosabilité post‑incident compatible avec les exigences probatoires.
2. Périmètre / Hors périmètre¶
2.1 Périmètre¶
Sont couverts par la présente spécification :
- le cycle de vie d’un job (soumission → exécution → état terminal),
- les garanties d’exécution (au plus une fois, échec explicite),
- la persistance des états et événements de jobs,
- la consultation des états et historiques,
- les contraintes de non‑blocage du flux principal,
- les exigences de sécurité du backend de queue (Redis),
- les critères d’acceptation testables et scénarios associés.
2.2 Hors périmètre (explicitement exclus)¶
Les éléments suivants sont hors périmètre et ne doivent pas être inférés :
- le choix d’une implémentation concrète (BullMQ, Celery, autre),
- le dimensionnement matériel (CPU, RAM, nombre de workers),
- les stratégies internes d’optimisation (batching, priorité interne),
- la politique exacte de monitoring graphique (Grafana, autre).
3. Définitions¶
- Job : unité de travail asynchrone identifiée par un identifiant unique immuable (
job_id). - État terminal : état final non transitoire d’un job (
SUCCEEDED,FAILED,CANCELLED). - Flux principal : traitement synchrone exposé par l’API backend.
- Backend de queue : composant persistant stockant jobs, états et événements.
- État consultable : état accessible via une interface définie et stable.
- Exécution au plus une fois : un job ne peut produire ses effets au maximum qu’une seule fois.
4. Invariants (non négociables)¶
I‑1 — Non‑blocage du flux principal¶
La soumission d’un job ne doit jamais bloquer le flux principal.
Règle mesurable : - la réponse HTTP de soumission doit être retournée indépendamment de l’exécution du job.
I‑2 — Exécution au plus une fois ou échec explicite¶
Un job doit satisfaire exactement une des conditions suivantes :
- être exécuté une seule fois avec succès,
- échouer de manière explicite et traçable.
Interdictions : - exécution multiple silencieuse, - redémarrage implicite sans trace, - succès partiel non détectable.
I‑3 — Politique d’absence de retry implicite¶
Aucune tentative automatique de ré‑exécution n’est autorisée sans règle explicite.
- Par défaut : 0 retry.
- Toute autre politique doit être explicitement définie (cf. §9).
I‑4 — Traçabilité obligatoire et persistante¶
Chaque job doit produire une trace persistante comprenant :
- son identifiant (
job_id), - son état courant,
- les timestamps d’entrée et de sortie de chaque état,
- la cause d’échec le cas échéant.
I‑5 — Persistance post‑terminal¶
Les données de jobs ne doivent pas disparaître automatiquement à l’atteinte d’un état terminal.
- La politique de rétention doit être définie explicitement.
I‑6 — Backend de queue sécurisé¶
Le backend de queue doit être considéré comme sensible et soumis à :
- authentification,
- chiffrement en transit,
- isolation logique.
5. Flux nominaux¶
FN‑1 — Soumission d’un job¶
- Le client appelle l’API de soumission.
- Le backend génère un
job_idunique. - Le job est persisté dans le backend de queue avec l’état
PENDING. - L’API retourne une réponse de succès sans attendre l’exécution.
FN‑2 — Exécution nominale¶
- Un worker récupère le job
PENDING. - L’état passe à
RUNNING. - Le traitement s’exécute.
- En cas de succès, l’état passe à
SUCCEEDED.
5bis. Diagrammes¶
D-1 — Machine d’etats d’un job¶
Les etats terminaux (SUCCEEDED, FAILED, CANCELLED) sont irreversibles (cf. I-2, I-5). Chaque transition produit une trace persistante avec timestamps (cf. I-4).
stateDiagram-v2
[*] --> PENDING : Soumission (FN-1)
PENDING --> RUNNING : Worker acquiert le job (FN-2)
RUNNING --> SUCCEEDED : Traitement OK (FN-2)
RUNNING --> FAILED : Erreur execution (CE-1)
PENDING --> CANCELLED : Annulation explicite
RUNNING --> CANCELLED : Annulation explicite
SUCCEEDED --> [*]
FAILED --> [*]
CANCELLED --> [*]
note right of PENDING
I-1 : la soumission ne bloque
jamais le flux principal
end note
note right of RUNNING
I-2 : un seul worker execute
le job (at-most-once)
end note
note left of FAILED
I-4 : cause d’echec
structuree obligatoire
end note D-2 — Sequence de soumission et execution nominale¶
Interactions entre le client API, le backend, le backend de queue (Redis) et le worker. Illustre la separation synchrone/asynchrone (cf. I-1) et la securite du transit (cf. I-6).
sequenceDiagram
participant C as Client API
participant B as Backend
participant Q as Backend de queue (Redis)
participant W as Worker
Note over Q: I-6 : auth + TLS + isolation
C->>B: POST /jobs (soumission)
B->>B: Generer job_id unique
B->>Q: Persister job (etat PENDING)
Q-->>B: ACK
B-->>C: 202 Accepted {job_id}
Note over C,B: I-1 : reponse immediate, pas d’attente worker
rect rgb(240, 248, 255)
Note over Q,W: Traitement asynchrone
W->>Q: Acquerir job PENDING
Q-->>W: Job (acquisition exclusive)
Note over W: I-2 : at-most-once
W->>Q: Transition PENDING → RUNNING (+ timestamp)
W->>W: Execution du traitement
alt Succes
W->>Q: Transition RUNNING → SUCCEEDED (+ timestamp)
else Echec
W->>Q: Transition RUNNING → FAILED (+ cause + timestamp)
Note over W,Q: I-4 : cause structuree obligatoire
end
end
C->>B: GET /jobs/{job_id}
B->>Q: Lire etat + historique
Q-->>B: Etat + timestamps
B-->>C: 200 {state, history}
Note over C,B: I-5 : donnees persistees post-terminal 6. Cas d’erreur¶
CE‑1 — Échec d’exécution¶
- Le job passe à l’état
FAILED. - Une cause d’échec structurée est enregistrée.
CE‑2 — Backend indisponible¶
- La soumission échoue explicitement.
- Aucun job fantôme ne doit être créé.
CE‑3 — Queue inexistante¶
- La soumission doit échouer explicitement.
- Le comportement silencieux est interdit.
7. Critères d’acceptation (testables)¶
CA‑1 — Non‑blocage¶
Mesure : la réponse de soumission est retournée même si aucun worker n’est actif.
CA‑2 — Unicité d’exécution¶
Mesure : un même
job_idne peut produire qu’un seul effet observé.
CA‑3 — Traçabilité consultable¶
Mesure : l’état et l’historique d’un job sont accessibles via une interface définie.
CA‑4 — Persistance post‑terminal¶
Mesure : un job terminal reste consultable après exécution.
CA‑5 — Sécurité du backend¶
Mesure : toute connexion non authentifiée ou non chiffrée est refusée.
8. Scénarios de test (Given / When / Then)¶
ST‑1 — Soumission sans worker¶
Given aucun worker actif
When un job est soumis
Then l’API répond avec succès et le job est en état PENDING.
ST‑2 — Exécution unique¶
Given un job PENDING
When deux workers tentent de l’exécuter
Then un seul passe à RUNNING, l’autre échoue explicitement.
ST‑3 — Consultation post‑échec¶
Given un job en état FAILED
When l’état est consulté
Then la cause d’échec est lisible.
9. Hypothèses explicites¶
- Le backend de queue dispose d’un mécanisme de persistance durable.
- Les horodatages sont fournis par une source fiable.
- Les identifiants de job sont globalement uniques.
10. Points à clarifier¶
Les points suivants doivent être décidés explicitement avant implémentation :
- Politique exacte de rétention post‑terminal (durée, purge).
- Existence ou non de retries explicites et leurs règles.
- Interface exacte de consultation des états (API, DB, autre).
- Niveau d’isolation du Redis (dédié vs mutualisé).
- Limites de charge et mécanismes anti‑DoS côté workers.
Fin de spécification — toute implémentation non conforme est invalide.