rollfuse
← Voltar ao blog

Conduzindo um Rollout Progressivo a Partir de um Serviço Go

Um rollout progressivo é um recurso Rollout anexado a um EnvironmentFlagConfig: uma variação alvo e uma sequência de estágios, cada um com um percentual alvo e um horário de ativação. A API avança o tráfego conforme o cronograma; um guardrail anexado ao rollout pode abortá-lo automaticamente se uma métrica for violada. Nada disso exige tocar no caminho de código do seu serviço além de uma coisa: avaliar a flag que o go-sdk já mantém em cache localmente.

Criando o rollout

POST /v1/environment-flag-configs/{environment_flag_config_id}/rollouts
{
  "target_variation_id": "...",
  "stages": [
    { "target_percentage": 5,   "activate_at": "2026-09-01T14:00:00Z" },
    { "target_percentage": 25,  "activate_at": "2026-09-01T14:10:00Z" },
    { "target_percentage": 50,  "activate_at": "2026-09-01T14:25:00Z" },
    { "target_percentage": 100, "activate_at": "2026-09-01T14:40:00Z" }
  ]
}

Criar um rollout exige um membro logado com a permissão rollouts:manage, no console ou pela API com a sessão desse membro; uma service credential não consegue. (O repositório github-action faz outra coisa: avalia uma flag dentro de um workflow e falha o passo quando a variação não bate, o que serve pra travar um passo de deploy.) Os percentuais dos estágios precisam crescer estritamente e o estágio final precisa cair em exatamente 100; a API rejeita uma sequência malformada de cara, em vez de deixar um rollout empacar no meio.

Anexando um guardrail

POST /v1/rollouts/{rollout_id}/guardrails
{
  "metric_definition_id": "...",
  "comparison_operator": "gt",
  "threshold": 0.4,
  "evaluation_window_seconds": 300
}

A definição de métrica não guarda consulta: os valores de p95 chegam ao rollfuse como observações, enviadas pela API ou puxadas por um conector, como explica o post como monitorar um rollout progressivo. O guardrail é avaliado periodicamente enquanto o rollout roda, não uma vez por estágio, tirando a média das observações da janela: uma regressão que só aparece quando o tráfego cruza de 5% pra 25% ainda é pega. Se a média passa do limite, o rollout aborta automaticamente e a flag volta a servir a variação padrão para 100% do ambiente; nada no seu serviço Go precisa reagir a isso, já que a próxima chamada de Evaluate simplesmente lê a Configuration revertida.

Avaliando a flag alvo

result, err := client.Evaluate(subjectKey, "checkout-redesign",
    rollfuse.WithFallback(false), // usado só se ainda não houver Configuration em cache
)
if err != nil {
    // trate o erro (ErrConfigNotReady, ErrFlagNotFound)
}

var enabled bool
_ = json.Unmarshal(result.Value, &enabled)

if enabled {
    // essa requisição caiu no percentual ativo do rollout
}

O go-sdk não sabe nem se importa que um rollout está em andamento; ele avalia o que a Configuration em cache atual diz, e o trabalho do rollout é mudar o que essa Configuration diz conforme os estágios avançam. É a mesma chamada Evaluate que seu serviço já faz pra qualquer flag; um rollout progressivo muda o formato do tráfego por trás dela, não o ponto de chamada.

Observando o rollout acontecer

O console mostra o progresso dos estágios do rollout e os guardrails dele, se atualiza sozinho e guarda o histórico de avaliações de cada guardrail. Pra alimentar o guardrail com métricas que você já coleta, veja como monitorar um rollout progressivo, que mostra como levar valores do Prometheus pro rollfuse, enviados pela API ou puxados por um conector.