Zum Inhalt springen

Einen Fleet-Worker betreiben

Starte cc_worker auf einer freien Maschine, um deiner Flotte Ausführungskapazität zu geben. Es ist eine Binärdatei in reinem Dart — ohne Flutter-Engine —, die sich mit einem cc_server koppelt, die Fähigkeiten des Hosts meldet, Heartbeats schickt, befristet zugewiesene Jobs abholt, sie ausführt und Prozessereignisse zurückstreamt. Sie hält keinen dauerhaften Zustand: Ein Supervisor startet sie neu, und sie registriert sich wieder.

Zuerst brauchst du einen laufenden cc_server — siehe Einen Headless-Server betreiben.

Ein gekoppelter Worker registriert sich, schickt Heartbeats und wartet auf befristet zugewiesene Jobs. Arbeit reichst du mit fleet.submitJob ein. Das Dispatch von Agenten auf diesem Server läuft nicht über die Flotte; das Zeichen, dass diese Anleitung geklappt hat, ist der Worker im Flottenbereich mit einem frischen Heartbeat. Der Worker, der beim Start im Prozess registriert wird, hat eine leere Runner-Map, deshalb liefert ein Job, der auf ihm landet, No local runner for job kind ….

  • Das Dart SDK. Dieses Repo pinnt sein SDK mit fvm, deshalb stellst du den Befehlen fvm voran.
  • Dieses Repository, ausgecheckt auf der Worker-Maschine.
  • Ein erreichbarer cc_server (Loopback für die Entwicklung, LAN oder entfernt für den Betrieb).
  • git auf dem PATH — der Worker materialisiert Repos und führt git-Sonden aus.
Terminalfenster
cd apps/cc_worker
fvm dart build cli

Das erzeugt ein eigenständiges Bundle unter ./build/cli/<os_arch>/bundle/bin/cc_worker.

Schritt 2: Die Zugangsdaten des Workers ausstellen

Abschnitt betitelt „Schritt 2: Die Zugangsdaten des Workers ausstellen“

Ein cc_server nimmt nur einen Worker an, der eine ID eines gekoppelten Geräts und einen vorab geteilten Schlüssel vorlegt — das gilt auch für einen Loopback-Server. Stelle sie auf der Server-Maschine aus (pair kann laufen, während der Server läuft; das neue Gerät wird ohne Neustart übernommen):

Terminalfenster
cc_server pair --data-dir <dir> --device my-worker --label "Build box"

Ausgegeben werden Device id und Pairing key — das sind die Werte für --device-id und --psk / --psk-file / CC_WORKER_PSK.

Gegen einen gekoppelten Server:

Terminalfenster
./build/cli/<os_arch>/bundle/bin/cc_worker \
--server wss://host:9030 --device-id my-worker --psk-file /path/to/worker.psk

Gegen einen Loopback-Server (trotzdem gekoppelt — cc_server führt den PSK-Handshake immer aus):

Terminalfenster
fvm dart run cc_worker --server ws://localhost:9030 \
--device-id my-worker --psk-file /path/to/worker.psk
Flag Beschreibung Vorgabe
--server <url> URL von cc_server (ws:///wss://; http(s) und ein fehlender Pfad /rpc werden angepasst). Pflicht. —
--name <name> Name des Workers, wie du ihn als Betreiber siehst. Hostname
--device-id <id> Stabile ID des gekoppelten Geräts, zugleich die Worker-ID. cc-worker
--psk-file <path> Datei, deren erste nicht leere Zeile der Kopplungsschlüssel ist. Bevorzugt gegenüber --psk. —
--psk <key> Kopplungsschlüssel auf der Kommandozeile. Sichtbar in ps und in der Shell-Historie — die Binärdatei warnt. —
--max-jobs <n> Harte Obergrenze der Jobs, die dieser Prozess gleichzeitig ausführt (positive Ganzzahl). 4

Der Schlüssel wird in dieser Reihenfolge aufgelöst: --psk-file → CC_WORKER_PSK → --psk. Lässt du jede Quelle weg, überspringt der Worker seinen Auth-Handshake; ein echter cc_server lehnt die Sitzung dann ab (auth_denied), statt einen nicht authentifizierten Worker anzunehmen. Unbekannte Flags sind ein Verwendungsfehler (exit 64) — anders als cc_server nutzt diese Binärdatei package:args und ignoriert Tippfehler nicht.

CC_WORKER_CACHE überschreibt das Cache-Verzeichnis der Worktree-Materialisierung (Vorgabe: ein Verzeichnis cc_worker_cache unter dem temporären Verzeichnis des Systems).

Der Worker registriert sich mit fleet.registerWorker, schickt danach alle 20s einen Heartbeat und fragt alle 2s nach Leases. Er läuft bis SIGINT/SIGTERM; lege ihn unter systemd oder launchd, damit er nach einem Absturz oder Neustart neu startet und sich erneut registriert.

Öffne Observability in der Desktop- oder Web-App, wechsle auf den Tab Live und scrolle nach unten. Worker listet jeden registrierten Worker mit Plattform, Kernen, Fähigkeitsschlüsseln und letztem Heartbeat; Jobs listet die Jobs, die darüber verteilt sind.

Erscheint dein Worker dort mit einem aktuellen Heartbeat, haben Kopplung und Registrierung funktioniert.

Von der Kachel eines Workers kannst du ihn Entleeren (laufende Jobs zu Ende führen, keine neuen Leases annehmen), einen Worker, der geleert wird, Fortsetzen, seine Zugangsdaten Widerrufen oder die Zeile Entfernen.

Die Zeilen von Workern und Jobs liegen in der global.db des Servers — der Worker selbst schreibt außer dem Materialisierungs-Cache nichts auf die Platte.

Bei der Registrierung erkennt der Worker seine Fähigkeiten von selbst, und der Scheduler gleicht die Jobs damit ab. Von Hand stellst du das nicht ein:

  • Betriebssystem und Architektur (macos/linux/windows, arm64/x64) — genaue Sonden, mit Rückfall auf uname -m / PROCESSOR_ARCHITECTURE
  • Kerne und RAM — genaue Kernzahl; der RAM fällt auf 0, wenn er sich nicht sondieren lässt
  • flutter — gesetzt, wenn ein Flutter-SDK erreichbar ist (bloßes flutter, dann fvm flutter); Golden-Render-Jobs brauchen es
  • sandbox — native-macos unter macOS, native-linux unter Linux. Das ist ein Platzierungshinweis, kein Versprechen: Der Worker meldet das Backend, das seine Plattform hat, hüllt die Jobs, die er ausführt, aber nicht darin. Anders als cc_server startet cc_worker einen per Lease zugewiesenen Job direkt
  • always-on und parallel — ein dedizierter cc_worker meldet immer beide, deshalb ist er für Eval-Batches und andere parallele Wegwerfkapazität geeignet

Die Erkennung ist ein Best-Effort: Was sich nicht sondieren lässt, fällt auf einen sicheren Vorgabewert zurück, statt den Start scheitern zu lassen.

Das Lease-Protokoll trägt sechs Job-Arten:

Art Was es ist
agentRun Ein einzelner Agentenlauf (Dispatch)
pipelineStep Ausführung eines Pipeline-Schritts
codeIndex Aufbau eines Code-Index für ein Repo
goldenRender Ein visuelles Golden-Rendering der Oberfläche (braucht flutter)
benchmark Ein Performance-Benchmark
evalBatch Ein Eval-Batch (bevorzugt Kapazität mit parallel)

Die Ausführung ist eine echte Implementierung, die Subprozesse streamt, und keine voll eingebaute Agentenlaufzeit. Trägt eine Lease repoRemote, führt der Worker git clone --depth 1 in ein Cache-Verzeichnis aus, das nach Remote und SHA geschlüsselt ist, danach git fetch und git checkout. Bei agentRun führt er den Befehl aus CC_JOB_COMMAND in der Umgebung der Lease im Arbeitsverzeichnis aus und streamt stdout und stderr als Ereignisse zurück; fehlt CC_JOB_COMMAND, spiegelt er den Prompt zurück, damit der Transport trotzdem Ende zu Ende durchlaufen wird. Die anderen Arten führen kleine echte Befehle aus (git rev-parse HEAD, git --version), als ehrliche Sonden. Auf den Job begrenzte Zugangsdaten in der Lease-Umgebung werden in jeden Subprozess injiziert und nie in ein Log geschrieben.

Ereignisse werden gesammelt und alle 250ms oder alle 32 Ereignisse abgeschickt; jeder Job endet mit einem Done-Ereignis und einem Abschlussbericht. Das Modell sind Heartbeats plus Leases mit kurzer TTL: Verliert ein Worker den Kontakt, läuft seine Lease ab, und der Server nimmt den Job zur Wiederholung zurück. Auf dem Worker liegt kein dauerhafter Zustand, und zwischen den Workern gibt es weder Konsens noch Work-Stealing.