Skip to content

refactor(runner): link runner bits instead of copying them - #5

Merged
RedBoardDev merged 1 commit into
mainfrom
perf/link-runner-bits
Aug 14, 2026
Merged

RedBoardDev merged 1 commit into
mainfrom
perf/link-runner-bits

Conversation

@RedBoardDev

Copy link
Copy Markdown
Owner

Constat

Préparer un runner recopie l'intégralité de la release en cache dans son workdir. Mesuré sur l'hôte KARE :

runner installe (hors _work)   675 Mo
runners provisionnes / 24h     343
                             = 231 Go ecrits puis effaces chaque jour

pidstat sur cet hôte classe ghr premier écrivain disque de la machine, à 132 Mo/s en rafale, devant les Runner.Worker eux-mêmes. Pendant ces rafales la latence disque passe de 0,58 ms à 75,83 ms avec une file de 553 requêtes, ce qui fait déraper les steps Initialize containers et Stop containers des jobs (20 s → 1m43, 7 s → 1m51 sur un run mesuré).

Or ces fichiers sont en lecture seule pendant toute la vie du job : le runner écrit dans _work, _diag et les fichiers de configuration qu'il crée lui-même, jamais dans ses propres binaires. Le runner est lancé en JIT éphémère (ACTIONS_RUNNER_INPUT_JITCONFIG), donc il ne se met pas à jour lui-même non plus.

Changement

copyFile tente os.Link et retombe sur la copie octet par octet si le lien est refusé (autre système de fichiers, limite de liens). Le comportement est donc inchangé partout où le lien est impossible. Les répertoires et les liens symboliques gardent leur traitement existant, y compris les gardes contre les symlinks absolus ou qui s'échappent.

Tests

Deux tests ajoutés : l'un vérifie que les fichiers réguliers sont bien liés (os.SameFile), l'autre que le repli en copie produit un fichier indépendant quand os.Link échoue. Les 362 tests du dépôt passent, gofmt et go vet sont propres.

Risque à connaître

Les fichiers du workdir partagent désormais leur inode avec le cache. Si un jour quelque chose écrit en place dans un fichier du runner, la modification atteindrait le cache partagé et casserait tous les runners provisionnés ensuite. Le commentaire dans le code nomme ce piège.

Preparing a runner duplicated the whole cached release into its workdir. On the
KARE host that is 675MB per runner and 343 runners a day, so ~231GB written and
deleted daily, which made ghr the single largest disk writer on the box while
the runner bits are read-only for the job's lifetime.

copyFile now hardlinks and falls back to the byte copy when the link is refused
(cross-device, link limit), so behaviour is unchanged everywhere the link cannot
be made. Directories and symlinks keep their existing handling.
@RedBoardDev
RedBoardDev force-pushed the perf/link-runner-bits branch from 28e2471 to 495983e Compare August 14, 2026 17:43
@RedBoardDev
RedBoardDev merged commit e8e2639 into main Aug 14, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant