Pular para o conteúdo

Executar um worker da frota

Execute o cc_worker em uma máquina ociosa para adicionar capacidade de execução à sua frota. Ele é um binário em Dart puro — sem engine do Flutter — que se emparelha com um cc_server, declara as capacidades do host, envia heartbeats, busca tarefas em lease, executa-as e transmite os eventos de processo de volta. Ele não detém nenhum estado durável: um supervisor o reinicia e ele se registra novamente.

Você precisa de um cc_server em execução primeiro — consulte Executar um servidor headless.

Um worker emparelhado se registra, envia heartbeats e aguarda tarefas em lease. Envie trabalho com fleet.submitJob. O despacho de agentes nesse servidor não passa pela frota; o sinal de sucesso deste guia é o worker aparecendo no painel da frota com um heartbeat recente. O worker no próprio processo, registrado na inicialização, tem um mapa de executores vazio, então uma tarefa colocada nele retorna No local runner for job kind ….

  • O Dart SDK. Este repositório fixa o SDK dele com fvm, então prefixe os comandos com fvm.
  • Este repositório clonado na máquina do worker.
  • Um cc_server alcançável (loopback para desenvolvimento, LAN ou remoto para produção).
  • git no PATH — o worker materializa repos e executa sondagens com git.
Janela do terminal
cd apps/cc_worker
fvm dart build cli

Isso produz um pacote autocontido em ./build/cli/<os_arch>/bundle/bin/cc_worker.

Um cc_server só aceita um worker que apresente um id de dispositivo emparelhado e uma chave pré-compartilhada — inclusive um servidor em loopback. Emita-os na máquina do servidor (pair pode rodar com o servidor no ar; o novo dispositivo é reconhecido sem reinício):

Janela do terminal
cc_server pair --data-dir <dir> --device my-worker --label "Build box"

Ele imprime um Device id e uma Pairing key — são esses valores que --device-id e --psk / --psk-file / CC_WORKER_PSK aceitam.

Com um servidor emparelhado:

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

Com um servidor em loopback (ainda emparelhado — o cc_server sempre executa o handshake de PSK):

Janela do terminal
fvm dart run cc_worker --server ws://localhost:9030 \
--device-id my-worker --psk-file /path/to/worker.psk
Flag Descrição Padrão
--server <url> URL do cc_server (ws:///wss://; http(s) e um caminho /rpc ausente são convertidos). Obrigatório. —
--name <name> Nome do worker exibido ao operador. nome do host
--device-id <id> Id estável de dispositivo emparelhado, também usado como id do worker. cc-worker
--psk-file <path> Arquivo cuja primeira linha não vazia é a chave de emparelhamento. Preferido em vez de --psk. —
--psk <key> Chave de emparelhamento na linha de comando. Visível em ps e no histórico do shell — o binário avisa. —
--max-jobs <n> Teto rígido de tarefas que este processo executa simultaneamente (inteiro positivo). 4

A ordem de resolução da chave é --psk-file → CC_WORKER_PSK → --psk. Omitir todas as fontes pula o handshake de autenticação do worker; um cc_server de verdade então nega a sessão (auth_denied) em vez de aceitar um worker não autenticado. Flags desconhecidas são erro de uso (exit 64) — ao contrário do cc_server, este binário usa package:args e não ignora erros de digitação.

CC_WORKER_CACHE substitui o diretório de cache de materialização de worktrees (padrão: um diretório cc_worker_cache sob o diretório temporário do sistema).

O worker se registra com fleet.registerWorker, depois envia heartbeat a cada 20s e consulta leases a cada 2s. Ele roda até receber SIGINT/SIGTERM; coloque-o sob systemd ou launchd para que reinicie e se registre novamente após uma falha ou reinicialização.

Abra Observabilidade no app de desktop ou web, mude para a aba Ao vivo e role até o final. Trabalhadores lista cada worker registrado com sua plataforma, núcleos, chaves de capacidade e último heartbeat; Trabalhos lista as tarefas distribuídas entre eles.

Ver o seu worker ali com um heartbeat recente é a confirmação de que o emparelhamento e o registro funcionaram.

No bloco de um worker você pode Drenar (concluir as tarefas atuais, não aceitar novos leases), Retomar um worker em drenagem, Revogar a credencial dele ou Remover a linha.

As linhas de workers e de tarefas ficam no global.db do servidor — o próprio worker não grava nada em disco além do cache de materialização.

No registro, o worker detecta automaticamente suas capacidades e o agendador combina as tarefas com elas. Você não configura nada disso à mão:

  • SO e arquitetura (macos/linux/windows, arm64/x64) — sondagens exatas, com fallback para uname -m / PROCESSOR_ARCHITECTURE
  • Núcleos e RAM — contagem exata de núcleos; a RAM degrada para 0 quando não é possível sondá-la
  • flutter — definida quando um SDK do Flutter está acessível (flutter puro, depois fvm flutter); tarefas de renderização golden exigem essa capacidade
  • sandbox — native-macos no macOS, native-linux no Linux. É uma dica de posicionamento, não uma promessa: o worker anuncia o backend que a plataforma dele tem, mas não envolve em sandbox as tarefas que executa. Ao contrário do cc_server, o cc_worker inicia uma tarefa em lease diretamente
  • always-on e parallel — um cc_worker dedicado sempre anuncia as duas, portanto é elegível para lotes de avaliação e outra capacidade paralela descartável

A detecção é de melhor esforço: tudo o que ela não conseguir sondar degrada para um padrão seguro em vez de falhar na inicialização.

O protocolo de lease carrega seis tipos de tarefa:

Tipo O que é
agentRun Uma única execução de agente (despacho)
pipelineStep A execução de uma etapa de pipeline
codeIndex A construção de um índice de código de um repo
goldenRender Uma renderização golden visual de UI (exige flutter)
benchmark Uma execução de benchmark de desempenho
evalBatch Um lote de avaliação (prefere capacidade parallel)

A execução é uma implementação real de streaming de subprocessos, não um runtime completo de agente embutido. Quando um lease carrega repoRemote, o worker faz git clone --depth 1 em um diretório de cache com chave de remote e SHA, depois git fetch e git checkout. Para agentRun, ele executa o comando em CC_JOB_COMMAND do env do lease no diretório de trabalho, transmitindo stdout e stderr de volta como eventos; sem CC_JOB_COMMAND, ele ecoa o prompt para que o transporte ainda seja exercitado de ponta a ponta. Os outros tipos executam pequenos comandos reais (git rev-parse HEAD, git --version) como sondagens honestas. As credenciais com escopo de tarefa no env do lease são injetadas em todo subprocesso e nunca gravadas em log.

Os eventos são agrupados e descarregados a cada 250ms ou a cada 32 eventos; cada tarefa termina com um evento done e um relatório de conclusão. O modelo é heartbeats mais leases de TTL curto: se um worker perde contato, o lease dele expira e o servidor recolhe a tarefa para nova tentativa. Não há estado durável no worker nem consenso ou roubo de trabalho entre workers.