

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Contoh skenario
<a name="java-flow-making-changes-example-scenario"></a>

Ada kelas perubahan kode yang dianggap tidak kompatibel ke belakang. Perubahan ini mencakup pembaruan yang mengubah nomor, jenis, atau urutan tugas terjadwal. Pertimbangkan contoh berikut:

Anda menulis kode decider untuk menjadwalkan dua tugas timer. Anda memulai eksekusi dan menjalankan keputusan. Akibatnya, dua tugas timer dijadwalkan, dengan IDs `1` dan`2`.

Jika Anda memperbarui kode penentu untuk menjadwalkan hanya satu timer sebelum keputusan berikutnya dieksekusi, selama tugas keputusan berikutnya, kerangka kerja akan gagal memutar ulang peristiwa `TimerFired` kedua, karena ID `2` tidak cocok dengan tugas timer apa pun yang dihasilkan kode.

## Skenario
<a name="example-scenario-outline"></a>

Garis besar berikut menunjukkan langkah-langkah skenario ini. Tujuan akhir dari skenario ini adalah untuk bermigrasi ke sistem yang hanya menjadwalkan satu timer tetapi tidak menyebabkan kegagalan dalam eksekusi yang dimulai sebelum migrasi.

1. Versi Decider Awal

   1. Tulis decider.

   1. Mulai decider.

   1. Decider menjadwalkan dua timer.

   1. Decider mulai lima eksekusi.

   1. Hentikan decider.

1. Perubahan Decider Tidak Kompatibel untuk Mundur

   1. Modifikasi decider.

   1. Mulai decider.

   1. Decider menjadwalkan satu timer.

   1. Decider mulai lima eksekusi.

Bagian berikut termasuk contoh kode Java yang menunjukkan bagaimana menerapkan skenario ini. Contoh kode di [Solusi](java-flow-making-changes-solutions.md) menunjukkan berbagai cara untuk memperbaiki perubahan yang tidak kompatibel ke belakang.

**catatan**  
Anda dapat menggunakan versi terbaru [AWS SDK untuk Java](https://aws.amazon.com/sdk-for-java/) untuk menjalankan kode ini.

## Kode Umum
<a name="common-code"></a>

Kode Java berikut tidak berubah di antara contoh-contoh dalam skenario ini.

`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;
    }
 
}
```

## Menulis Kode Decider Awal
<a name="writing-initial-decider-code"></a>

Berikut ini adalah kode Java awal dari decider. Ini terdaftar sebagai versi `1` dan menjadwalkan dua tugas timer lima detik.

`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);
        }
 
    }
}
```

## Mensimulasikan Perubahan yang Tidak Kompatibel untuk Mundur
<a name="simulate-non-backwards-compatible-change"></a>

Kode Java decider berikut yang dimodifikasi adalah contoh yang baik dari perubahan yang tidak kompatibel ke belakang. Kode ini masih terdaftar sebagai versi `1`, tetapi hanya menjadwalkan satu timer.

`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);
        }
 
    }
}
```

Berikut kode Java memungkinkan Anda untuk mensimulasikan masalah membuat perubahan kebelakang yang kompatibel dengan menjalankan decider dimodifikasi.

`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();
    }
 
}
```

Saat Anda menjalankan program, tiga eksekusi yang gagal adalah yang dimulai di bawah versi awal dari penentu dan dilanjutkan setelah migrasi.