

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Escenario de ejemplo
<a name="java-flow-making-changes-example-scenario"></a>

Hay una clase de cambios de códigos que se considera que no son compatibles con las versiones anteriores. Estos cambios incluyen actualizaciones que modifican el número, tipo u orden de las tareas programadas. Considere el siguiente ejemplo:

Escribe código decisor para programar dos tareas de temporizador. Comienza la ejecución y ejecuta una decisión. Como resultado, se programan dos tareas temporizadas, con IDs `1` y. `2`

Si actualiza el código decisor para programar solo un temporizador antes de la ejecución de la siguiente decisión, durante la siguiente tarea de decisión el marco de trabajo producirá un error al reproducir el segundo evento `TimerFired`, porque el ID `2` no coincide con ninguna tarea del temporizador producida por el código.

## Esquema del escenario
<a name="example-scenario-outline"></a>

El siguiente esquema muestra los pasos de este escenario. El objetivo final del escenario es migrar a un sistema que solo programa un temporizador pero que no provoca errores en las ejecuciones iniciadas antes de la migración.

1. La versión inicial del decisor

   1. Escriba el decisor.

   1. Inicie el decisor.

   1. El decisor programa dos temporizadores.

   1. El decisor comienza cinco ejecuciones.

   1. Detenga el decisor.

1. Cambio de decisor no compatible con versiones anteriores

   1. Modifique el decisor.

   1. Inicie el decisor.

   1. El decisor programa un temporizador.

   1. El decisor comienza cinco ejecuciones.

Las siguientes secciones incluyen ejemplo de código Java que muestran como implementar este escenario. Los ejemplos de código en la sección [Soluciones](java-flow-making-changes-solutions.md) muestran diferentes maneras de solucionar cambios que no son compatibles con las versiones anteriores.

**nota**  
Puede utilizar la última versión del [AWS SDK para Java](https://aws.amazon.com/sdk-for-java/) para ejecutar este código.

## Código común
<a name="common-code"></a>

El siguiente código Java no cambia de un ejemplo a otro en este escenario.

`SampleBase.java`

```
package sample;
 
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
 
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
import com.amazonaws.services.simpleworkflow.flow.JsonDataConverter;
import com.amazonaws.services.simpleworkflow.model.DescribeWorkflowExecutionRequest;
import com.amazonaws.services.simpleworkflow.model.DomainAlreadyExistsException;
import com.amazonaws.services.simpleworkflow.model.RegisterDomainRequest;
import com.amazonaws.services.simpleworkflow.model.Run;
import com.amazonaws.services.simpleworkflow.model.StartWorkflowExecutionRequest;
import com.amazonaws.services.simpleworkflow.model.TaskList;
import com.amazonaws.services.simpleworkflow.model.WorkflowExecution;
import com.amazonaws.services.simpleworkflow.model.WorkflowExecutionDetail;
import com.amazonaws.services.simpleworkflow.model.WorkflowType;
 
public class SampleBase {
 
    protected String domain = "DeciderChangeSample";
    protected String taskList = "DeciderChangeSample-" + UUID.randomUUID().toString();
    protected AmazonSimpleWorkflow service = AmazonSimpleWorkflowClientBuilder.defaultClient();
    {
        try {
            AmazonSimpleWorkflowClientBuilder.defaultClient().registerDomain(new RegisterDomainRequest().withName(domain).withDescription("desc").withWorkflowExecutionRetentionPeriodInDays("7"));
        } catch (DomainAlreadyExistsException e) {
        }
    }
 
    protected List<WorkflowExecution> workflowExecutions = new ArrayList<>();
 
    protected void startFiveExecutions(String workflow, String version, Object input) {
        for (int i = 0; i < 5; i++) {
            String id = UUID.randomUUID().toString();
            Run startWorkflowExecution = service.startWorkflowExecution(
                    new StartWorkflowExecutionRequest().withDomain(domain).withTaskList(new TaskList().withName(taskList)).withInput(new JsonDataConverter().toData(new Object[] { input })).withWorkflowId(id).withWorkflowType(new WorkflowType().withName(workflow).withVersion(version)));
            workflowExecutions.add(new WorkflowExecution().withWorkflowId(id).withRunId(startWorkflowExecution.getRunId()));
            sleep(1000);
        }
    }
 
    protected void printExecutionResults() {
        waitForExecutionsToClose();
        System.out.println("\nResults:");
        for (WorkflowExecution wid : workflowExecutions) {
            WorkflowExecutionDetail details = service.describeWorkflowExecution(new DescribeWorkflowExecutionRequest().withDomain(domain).withExecution(wid));
            System.out.println(wid.getWorkflowId() + " " + details.getExecutionInfo().getCloseStatus());
        }
    }
 
    protected void waitForExecutionsToClose() {
        loop: while (true) {
            for (WorkflowExecution wid : workflowExecutions) {
                WorkflowExecutionDetail details = service.describeWorkflowExecution(new DescribeWorkflowExecutionRequest().withDomain(domain).withExecution(wid));
                if ("OPEN".equals(details.getExecutionInfo().getExecutionStatus())) {
                    sleep(1000);
                    continue loop;
                }
            }
            return;
        }
    }
 
    protected void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
 
}
```

`Input.java`

```
package sample;
 
public class Input {
 
    private Boolean skipSecondTimer;
 
    public Input() {
    }
 
    public Input(Boolean skipSecondTimer) {
        this.skipSecondTimer = skipSecondTimer;
    }
 
    public Boolean getSkipSecondTimer() {
        return skipSecondTimer != null && skipSecondTimer;
    }
 
    public Input setSkipSecondTimer(Boolean skipSecondTimer) {
        this.skipSecondTimer = skipSecondTimer;
        return this;
    }
 
}
```

## Escritura del código del decisor inicial
<a name="writing-initial-decider-code"></a>

A continuación se muestra el código Java inicial del decisor. Está registrado como versión `1` y programa dos tareas de temporizador de cinco segundos.

`InitialDecider.java`

```
package sample.v1;
 
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) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
            clock.createTimer(5);
        }
 
    }
}
```

## Simulación de un cambio no compatible con versiones anteriores
<a name="simulate-non-backwards-compatible-change"></a>

El siguiente código Java modificado del decisor en un buen de cambio no compatible con versiones anteriores. El código sigue estando registrado como versión `1` pero programa solo un temporizador.

`ModifiedDecider.java`

```
package sample.v1.modified;
 
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 modified) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
        }
 
    }
}
```

El siguiente código Java le permite simular el problema de hacer cambios que no son compatibles con versiones anteriores ejecutando el decisor modificado.

`RunModifiedDecider.java`

```
package sample;
 
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
 
public class BadChange extends SampleBase {
 
    public static void main(String[] args) throws Exception {
        new BadChange().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 the modified version of the decider
        WorkflowWorker after = new WorkflowWorker(service, domain, taskList);
        after.addWorkflowImplementationType(sample.v1.modified.Foo.Impl.class);
        after.start();
 
        // Start a few more executions
        startFiveExecutions("Foo.sample", "1", new Input());
 
        printExecutionResults();
    }
 
}
```

Cuando ejecuta el programa, las tres ejecuciones en las que se produce un error son aquellas que comenzaron bajo la versión inicial del decisor y que continuaron después de la migración.