

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Soluções
<a name="java-flow-making-changes-solutions"></a>

Você pode usar as seguintes soluções para evitar alterações incompatíveis com versões anteriores. Para obter mais informações, consulte [Como fazer alterações no código do agente de decisão](java-flow-making-changes-decider-code.md) e [Cenário de exemplo](java-flow-making-changes-example-scenario.md).

## Usar versionamento
<a name="use-versioning"></a>

Nesta solução, você copia o agente de decisão em uma classe nova, modifica o agente de decisão e o registra em uma versão nova do fluxo de trabalho.

`VersionedDecider.java`

```
package sample.v2;
 
import com.amazonaws.services.simpleworkflow.flow.DecisionContext;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
 
import sample.Input;
 
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60, defaultTaskStartToCloseTimeoutSeconds = 5)
public interface Foo {
 
    @Execute(version = "2")
    public void sample(Input input);
 
    public static class Impl implements Foo {
 
        private DecisionContext decisionContext = new DecisionContextProviderImpl().getDecisionContext();
        private WorkflowClock clock = decisionContext.getWorkflowClock();
 
        @Override
        public void sample(Input input) {
            System.out.println("Decision (V2) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
        }
 
    }
 
}
```

No código Java atualizado, o segundo operador de agente de decisão executa as duas versões do fluxo de trabalho permitindo que as execuções em andamento continuem a ser executadas independentemente da alterações na versão `2`.

`RunVersionedDecider.java`

```
package sample;
 
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
 
public class VersionedChange extends SampleBase {
 
    public static void main(String[] args) throws Exception {
        new VersionedChange().run();
    }
 
    public void run() throws Exception {
        // Start the first version of the decider, with workflow version 1
        WorkflowWorker before = new WorkflowWorker(service, domain, taskList);
        before.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        before.start();
 
        // Start a few executions with version 1
        startFiveExecutions("Foo.sample", "1", new Input());
 
        // Stop the first decider worker and wait a few seconds 
        // for its pending pollers to match and return
        before.suspendPolling();
        sleep(2000);
 
        // At this point, three executions are still open, with more decisions to make
 
        // Start a worker with both the previous version of the decider (workflow version 1) 
        // and the modified code (workflow version 2)
        WorkflowWorker after = new WorkflowWorker(service, domain, taskList);
        after.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        after.addWorkflowImplementationType(sample.v2.Foo.Impl.class);
        after.start();
 
        // Start a few more executions with version 2
        startFiveExecutions("Foo.sample", "2", new Input());
 
        printExecutionResults();
    }
 
}
```

Quando você executa o programa, todas as execuções são concluídas com êxito.

## Uso de sinalizadores de recursos
<a name="use-feature-flags"></a>

Outra solução de problemas de compatibilidade com versões anteriores é ramificar o código para oferecer suporte a duas implementações na mesma classe com base nos dados de entrada e não nas versões do fluxo de trabalho.

Ao usar essa abordagem, você adiciona campos (ou modifica os campos existentes) a seus objetos de entrada sempre que introduz alterações importantes. Em execuções iniciadas antes da migração, o objeto de entrada não terá o campo (ou terá um valor diferente). Portanto, você não precisa aumentar o número da versão.

**nota**  
Se você adicionar novos campos, verifique se o processo de desserialização do JSON é compatível com versões anteriores. Os objetos serializados antes da introdução do campo ainda devem ser desserializados com êxito após a migração. Como o JSON define um valor `null` sempre que um campo está ausente, use sempre tipos demarcados (`Boolean` em vez de `boolean`) e trate dos casos em que o valor é `null`.

`FeatureFlagDecider.java`

```
package sample.v1.featureflag;
 
import com.amazonaws.services.simpleworkflow.flow.DecisionContext;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
 
import sample.Input;
 
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60, defaultTaskStartToCloseTimeoutSeconds = 5)
public interface Foo {
 
    @Execute(version = "1")
    public void sample(Input input);
 
    public static class Impl implements Foo {
 
        private DecisionContext decisionContext = new DecisionContextProviderImpl().getDecisionContext();
        private WorkflowClock clock = decisionContext.getWorkflowClock();
 
        @Override
        public void sample(Input input) {
            System.out.println("Decision (V1 feature flag) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
            if (!input.getSkipSecondTimer()) {
                clock.createTimer(5);
            }
        }
 
    }
}
```

No código Java atualizado, o código das duas versões do fluxo de trabalho ainda está registrado para a versão `1`. No entanto, após a migração, as novas execuções são iniciadas com o campo `skipSecondTimer` dos dados de entrada definido como `true`.

`RunFeatureFlagDecider.java`

```
package sample;
 
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
 
public class FeatureFlagChange extends SampleBase {
 
    public static void main(String[] args) throws Exception {
        new FeatureFlagChange().run();
    }
 
    public void run() throws Exception {
        // Start the first version of the decider
        WorkflowWorker before = new WorkflowWorker(service, domain, taskList);
        before.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        before.start();
 
        // Start a few executions
        startFiveExecutions("Foo.sample", "1", new Input());
 
        // Stop the first decider worker and wait a few seconds 
        // for its pending pollers to match and return
        before.suspendPolling();
        sleep(2000);
 
        // At this point, three executions are still open, with more decisions to make
 
        // Start a new version of the decider that introduces a change 
        // while preserving backwards compatibility based on input fields
        WorkflowWorker after = new WorkflowWorker(service, domain, taskList);
        after.addWorkflowImplementationType(sample.v1.featureflag.Foo.Impl.class);
        after.start();
 
        // Start a few more executions and enable the new feature through the input data
        startFiveExecutions("Foo.sample", "1", new Input().setSkipSecondTimer(true));
 
        printExecutionResults();
    }
 
}
```

Quando você executa o programa, todas as execuções são concluídas com êxito.