> For the complete documentation index, see [llms.txt](https://docs.skail.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skail.dev/aprender/fundamentos/versionamento-de-codigo-com-execucoes-em-andamento.md).

# Versionamento de código com execuções em andamento

Uma execução que hibernou há três dias é retomada pelo código da versão em que ela começou: se `SKAIL_WORKLOAD` era `faturamento:v1.0.0`, é a `v1.0.0` que precisa estar publicada quando ela acordar. Esta página explica o que pode mudar nesse código sem quebrar a retomada, o que não pode, e como versionar quando precisa mudar o fluxo.

## Por que isso é um problema

A retomada é um replay: o runtime chama a function desde o início e confere cada `await` contra o histórico gravado. O histórico tem a sequência de passos da versão do código que começou a execução. Se o código publicado agora alcança um `await` diferente na mesma posição, o replay diverge e o runtime lança `SkailNonDeterministicException`. Ver [Determinismo e replay](/aprender/fundamentos/determinismo-e-replay.md).

Cada function tem um endereço, a URI, formada por `nome-do-workload:versao/NomeDoMetodo` (por exemplo `faturamento:v1.0.0/EmitirFatura`). A versão vem de `SKAIL_WORKLOAD`. Uma execução em andamento referencia as URIs da versão em que começou, e é para elas que a retomada é endereçada.

## O que pode mudar sem versionar

O corpo de um `[SkailCommand]`. O command roda de novo só se ainda não gravou resultado; para os que já gravaram, o novo código nem é executado. Trocar a implementação de `CobrarCartao`, corrigir um bug de serialização, mudar a URL do gateway: tudo seguro.

Lógica pura dentro da function que não altera a sequência de `await`s: mensagens de log, cálculos intermediários, nomes de variáveis.

Adicionar functions e commands novos que só as execuções novas vão chamar.

## O que não pode mudar sem versionar

Dentro de uma function com execuções em andamento: inserir ou remover um `await` (command, `Delay`, `WhenAll`, `WhenAny`, `WaitForEvent`); trocar a ordem deles; trocar um command por outro na mesma posição; mudar a condição de um `if` que decide qual `await` vem em seguida a partir de dados que já estão no histórico; renomear o método da function ou de um command chamado por ela (o nome faz parte da URI gravada); mudar `SKAIL_WORKLOAD` para um nome ou versão diferente sem manter a anterior.

O sintoma é sempre o mesmo: `SkailNonDeterministicException` ou "Target method not found" na retomada das execuções antigas. As novas funcionam; as que estavam hibernadas quebram.

## Como versionar

Há duas ferramentas.

Versão do workload. `SKAIL_WORKLOAD=faturamento:v1.1.0` publica todas as functions e commands sob URIs novas. As execuções iniciadas na `v1.0.0` continuam endereçadas a `faturamento:v1.0.0/...` e são retomadas só por ela; não há migração automática para a versão nova. A `v1.0.0` precisa continuar publicada e rodando até a última dessas execuções terminar.

Versão do método, com `skailMethodName`. Quando só uma function mudou, mantenha a antiga e crie a nova com URI explícita:

```csharp
[SkailFunction(skailMethodName: "EmitirFatura")]        // fluxo antigo, mantido até as execuções em andamento terminarem
public async SkailTask EmitirFaturaV1(Guid faturaId) { ... }

[SkailFunction(skailMethodName: "EmitirFaturaV2")]      // fluxo novo, é para este que os novos triggers apontam
public async SkailTask EmitirFatura(Guid faturaId) { ... }
```

O `skailMethodName` aceita só o nome (`workload/nome`) ou `nome:versao/metodo` para apontar para outra imagem. Ver a referência de [SkailFunction](/construir/sdk-.net/skailfunction.md).

## O procedimento que recomendamos

1. Antes de mudar o fluxo de uma function, veja no Monitor se há execuções em andamento ou hibernadas dela. Se não há, mude à vontade.
2. Se há, não edite a function: crie a nova versão (método novo com `skailMethodName`, ou nova versão do workload) e aponte os novos triggers para ela.
3. Mantenha a versão antiga publicada até a última execução dela terminar. Fluxos com esperas longas (um `Delay` de 30 dias, um `WaitForEvent` sem prazo) podem manter a versão antiga viva por semanas; conte com isso ao planejar.
4. Remova a versão antiga quando o Monitor mostrar zero execuções nela.

Se você já mudou e as execuções antigas quebraram: elas aparecem no Monitor como falhas com `SkailNonDeterministicException`. Publique de volta a versão antiga da function (com o mesmo nome e a mesma sequência de `await`s) e retome-as manualmente.

## Próximos passos

[Como fazer deploy de uma nova versão do workload](/construir/configurar-e-hospedar/como-fazer-deploy-de-uma-nova-versao-do-workload.md) tem os passos no portal e na pipeline. [Deploy sem quebrar execuções em andamento](/operar/deploy-sem-quebrar-execucoes-em-andamento.md) é o checklist para produção. A referência de [SkailFunction](/construir/sdk-.net/skailfunction.md) detalha o `skailMethodName`.
