lardon3d/docs/architecture/scheduler_resource_integration.md
2026-08-07 07:23:57 +02:00

90 lines
3.6 KiB
Markdown

# Intégration du scheduler et du gouverneur
## Responsabilités
Le scheduler conserve l'ordre FIFO et exécute les callbacks. Il ne calcule
jamais les budgets : la RAM, le GPU, les CPU, les slots IO et la taille de lot
sont exclusivement arbitrés par le Resource Governor.
Le cycle d'exécution est strict :
```text
Task
→ Resource Estimate
→ Governor
→ Reservation
→ Task Queue
→ Worker
→ Release Reservation
```
Chaque tâche reçoit une estimation immuable à sa création. Son passage de
`PENDING` à `RUNNING` est interdit tant que le gouverneur n'a pas créé une
réservation active. Le callback ne reçoit pas l'objet opaque : il consulte une
copie du contrat contenant le lot, la RAM, la mémoire GPU, les CPU et les slots
accordés.
## Admission
Le worker examine la première tâche FIFO. `WAIT` la laisse en attente et le
worker dort sur la condition de la file. Une libération de ressources suivie de
`lardon3d_task_queue_resources_changed()` le réveille sans polling.
`REDUCE_BATCH` crée un contrat avec le lot réduit, qui est transmis à la tâche.
`REJECT` place la tâche en échec sans appeler son callback et conserve la raison
explicite du gouverneur.
Après succès, échec ou annulation, le worker libère exactement une fois la
réservation puis réveille la file. La destruction annule les tâches, rejoint le
worker et libère toute réservation détenue avant de détruire les tâches.
## Pause
Dans cette première version, une tâche déjà démarrée conserve sa réservation
pendant `PAUSED`. Ses ressources restent donc indisponibles pour les autres
tâches. Ce choix évite de reprendre un callback avec un contrat qui aurait été
attribué entre-temps à un autre travail.
## Exécution séquencée adaptative
Une tâche peut s'exécuter en plusieurs séquences (lots) successives. Le
callback appelle `lardon3d_task_sequence_break()` pour libérer sa réservation
courante, capturer un nouvel instantané système, obtenir une nouvelle
réservation auprès du gouverneur et reprendre avec un contrat actualisé.
Le cycle d'une séquence est strict :
```text
Callback
→ sequence_break
→ Release Reservation courante
→ Snapshot système
→ Governor → Reservation
→ Contrat actualisé
→ Reprise du callback
```
Le task conserve une référence au gouverneur et à sa réservation courante.
`lardon3d_task_start` stocke la réservation initiale ; à la fin de l'exécution,
il libère la réservation courante si elle est encore détenue. Le worker de la
file libère ensuite la réservation d'origine, qui est déjà libérée si une
séquence a eu lieu : cet appel est alors sans effet.
Invariants préservés :
- Aucun callback ne démarre sans réservation active.
- Une seule réservation active par tâche à tout instant.
- La réservation est toujours valide avant et après un `sequence_break`.
- Le contrat est mis à jour atomiquement sous le mutex de la tâche.
- Si pause ou annulation est demandée pendant le `sequence_break`, la fonction
retourne `false` et la tâche est annulée.
- Si le gouverneur répond `WAIT` ou `REJECT`, la fonction retourne `false` et
la tâche passe en échec sans bloquer le callback.
- La progression est conservée entre les séquences.
## Limites et extensions
La file possède un seul worker, reste strictement FIFO et ne gère ni priorité
ni dépendance. Une notification explicite est nécessaire lorsqu'un composant
extérieur libère une réservation. Les prochaines étapes pourront ajouter un
DAG, des priorités, des pools distincts CPU, IO et GPU sans déplacer les
décisions de ressources hors du gouverneur.