Bencher Protocole Runner
Le binaire runner et le serveur API communiquent via une unique connexion
WebSocket. Cette référence décrit ce protocole : les messages échangés, le cycle de vie du Job
qu’ils pilotent, et comment les délais d’attente et la reconnexion empêchent les Jobs de rester bloqués. C’est le
complément détaillé du guide Runners auto-hébergés.
Vous n’avez pas besoin de connaître tout cela pour exploiter un Runner avec runner up ;
ceci est fourni à des fins de transparence et pour quiconque construit des outils autour de l’API.
Connexion
Un Runner maintient une unique connexion WebSocket vers le serveur API pendant tout son cycle de vie. La même connexion gère à la fois l’assignation et l’exécution des Jobs, et elle reste ouverte d’un Job à l’autre, évitant une reconnexion et un handshake pour chacun.
- Point de terminaison :
/v0/runners/{runner}/channel - Authentification : la clé du Runner est envoyée sous forme d’en-tête
Authorization: Bearer bencher_runner_<key>lors de l’établissement de la connexion. - Taille des messages : chaque message est borné par la limite
request_body_max_bytesdu serveur (appliquée à la fois à la taille maximale du message et de la trame). Un message qui dépasse cette limite, tel qu’une charge utilecompletedtransportant un volume important destdout,stderrou de fichiers de sortie, est rejeté au niveau du protocole WebSocket.
Chaque message est un objet JSON avec un champ event qui identifie son type.
Messages du Runner
Messages envoyés du Runner vers le serveur.
| Event | Description | Charge utile |
|---|---|---|
ready | Le Runner est inactif et demande un Job | poll_timeout optionnel (1-900 s) et métadonnées runner (os, arch, version) |
running | La préparation du Job est terminée et le benchmark démarre | Aucune |
heartbeat | Signal de vie périodique (environ une fois par seconde) | Aucune |
completed | Le benchmark s’est terminé avec succès | job (UUID du Job) et results (sortie par itération) |
failed | Le benchmark a échoué | job (UUID du Job), results et error |
canceled | Accuse réception d’une annulation depuis le serveur | job (UUID du Job) |
Messages du serveur
Messages envoyés du serveur vers le Runner.
| Event | Description | Charge utile |
|---|---|---|
ack | Accuse réception d’un message reçu | job optionnel (UUID du Job) |
job | Assigne un Job réclamé au Runner | Le Job réclamé : son Spec, la configuration du Job, et un jeton de récupération OCI à courte durée de vie |
no_job | Le délai d’attente du poll a expiré sans Job disponible | Aucune |
cancel | Le Job a été annulé ou a expiré ; arrêter l’exécution | Aucune |
update | Le Runner doit se mettre à jour vers une nouvelle version | version, url (URL de téléchargement) et checksum (SHA-256) |
Le jeton de récupération OCI dans un message job est généré lorsque le Job est réclamé et n’est jamais stocké.
Il est limité au seul projet auquel le Job appartient, est en lecture seule (pull only), et a une courte durée de vie,
de sorte qu’un Runner compromis ne peut récupérer que les Images du projet du Job qu’il a réclamé.
Flux de connexion
Après s’être connecté, le Runner entre dans une boucle d’interrogation inactive,
envoyant ready jusqu’à ce que le serveur assigne un job
(ou renvoie no_job lorsque le poll expire, ou update lorsqu’une nouvelle version est disponible).
Une fois qu’il dispose d’un Job, le Runner envoie running,
diffuse des messages heartbeat pendant l’exécution du benchmark,
et termine par un message terminal completed ou failed.
Le serveur accuse réception de chaque message avec ack,
et la connexion reste ouverte afin que le Runner retourne à la boucle inactive pour le Job suivant.
Si un Job est annulé, le serveur répond à un heartbeat avec cancel.
Le Runner arrête le benchmark et répond avec canceled, ce dont le serveur accuse réception.
Cycle de vie du Job
Chaque Job traverse un ensemble fixe d’états au fur et à mesure qu’il est réclamé, exécuté et traité.
| De | Vers | Déclencheur |
|---|---|---|
| pending | claimed | Un Runner réclame le Job |
| pending | canceled | Un utilisateur annule le Job |
| claimed | running | Le Runner envoie running |
| claimed | failed | Le Runner envoie failed, ou le heartbeat expire |
| claimed | canceled | Un utilisateur annule le Job |
| running | completed | Le Runner envoie completed |
| running | failed | Le Runner envoie failed, ou le heartbeat expire |
| running | canceled | Un utilisateur annule le Job, ou le délai d’attente strict du Job est dépassé |
| completed | processed | Le serveur traite les résultats avec succès |
| failed | completed | Le Runner renvoie completed, écrasant un échec dû à l’expiration du heartbeat |
processed et canceled sont terminaux.
completed et failed sont quasi terminaux :
completed passe à processed une fois les résultats analysés,
et failed passe à completed si le Runner renvoie completed.
Chaque transition utilise un filtre de statut sur sa mise à jour en base de données,
de sorte qu’un Job modifié de façon concurrente est relu plutôt qu’écrasé.
Délais d’attente & récupération
Trois mécanismes complémentaires garantissent qu’un Job ne reste jamais bloqué, même si un Runner plante ou perd sa connexion.
Délai d’attente du heartbeat
Tant que la connexion est ouverte, un délai d’attente de lecture détecte un Runner connecté mais silencieux.
Seuls les messages de protocole valides réinitialisent le minuteur ;
le JSON invalide, les trames ping/pong et les messages binaires ne le font pas.
À l’expiration, un Job qui s’est exécuté plus longtemps que son délai d’attente plus un délai de grâce est marqué canceled,
et sinon marqué failed (le contact avec le Runner a été perdu).
Délai d’attente strict du Job
Le serveur impose une durée d’exécution maximale stricte, indépendante du comportement du Runner,
de sorte qu’un Runner bogué ou compromis ne puisse pas s’exécuter indéfiniment en envoyant des heartbeats.
Lorsque la limite (le délai d’attente du Job plus un délai de grâce) est dépassée,
le Job est marqué canceled et le Runner reçoit un message cancel.
Récupération après déconnexion
Si la connexion tombe alors qu’un Job est encore en cours,
le serveur planifie une vérification après le délai d’attente du heartbeat.
Si le Runner s’est reconnecté et a repris ses heartbeats, le Job continue ;
sinon, le Job est marqué failed, ou canceled s’il avait dépassé le délai d’attente strict.
Au démarrage, le serveur récupère également les Jobs claimed orphelins,
replanifie les délais d’attente des Jobs en cours,
et retraite les Jobs completed dont les résultats ont été stockés mais pas encore analysés.
Reconnexion & livraison des résultats
La reconnexion est prise en charge et idempotente.
Renvoyer running pour un Job déjà en cours ne fait que rafraîchir sa vivacité,
et renvoyer un message terminal completed, failed ou canceled est toujours sûr.
Les messages terminaux transportent l’UUID du Job et reçoivent un ack ;
si la connexion tombe avant l’arrivée de l’ack,
le Runner stocke le résultat et le renvoie lors de la prochaine connexion avant de redevenir inactif.
Le résultat completed réel d’un Runner peut même écraser un statut failed dû à l’expiration du heartbeat.
Aucune nouvelle tentative automatique
Un Job failed n’est pas réessayé automatiquement.
Un benchmark en échec est un signal, pas une erreur à cacher,
sa réexécution vous est donc laissée.
Sortie du Job
Lorsqu’un Runner envoie completed ou failed,
la sortie complète est stockée dans le même backend de stockage OCI utilisé pour les Images de conteneur,
au chemin {project}/output/v0/jobs/{job}.
La sortie stockée contient un tableau results par itération et, en cas d’échec, une chaîne error.
Chaque itération enregistre son exit_code, son stdout, son stderr,
ainsi qu’une carte de tous les fichiers de sortie collectés avec leur contenu.
Une fois la sortie stockée, le serveur exécute l’adaptateur du harnais de benchmark sur les résultats
pour analyser les Metrics et les Alerts dans le Report, faisant passer le Job à processed.
La sortie est renvoyée lorsqu’un Job est interrogé avec l’API GET /v0/projects/{project}/jobs/{job}.
La même limite request_body_max_bytes qui borne les messages WebSocket
plafonne la taille de la sortie qu’un Runner peut livrer.