

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

# Memahami Tugas di AWS Flow Framework Java
<a name="details"></a>

**Topics**
+ [Tugas](#details.task)
+ [Urutan eksekusi](#details.order)
+ [Eksekusi alur kerja](#details.workflow)
+ [Nondeterminisme](#details.non)

## Tugas
<a name="details.task"></a>

Primitif mendasar yang digunakan AWS Flow Framework untuk Java untuk mengelola eksekusi kode asinkron adalah kelas. `Task` Sebuah objek tipe `Task` mewakili pekerjaan yang harus dilakukan secara asinkron. Ketika Anda memanggil metode asinkronus, kerangka kerja menciptakan `Task` untuk mengeksekusi kode dalam metode itu dan menempatkannya dalam daftar untuk eksekusi di lain waktu. Demikian pula, ketika Anda memanggil `Activity`, sebuah `Task` diciptakan untuk itu. Pemanggilan metode kembali setelah ini, biasanya mengembalikan `Promise<T>` sebagai hasil pemanggilan di masa mendatang.

Kelas `Task` adalah publik dan dapat digunakan secara langsung. Sebagai contoh, kita dapat menulis ulang contoh Hello World untuk menggunakan `Task` bukan metode asinkronus.

```
@Override
public void startHelloWorld(){
       final Promise<String> greeting = client.getName();
        new Task(greeting) {
        @Override
        protected void doExecute() throws Throwable {
        	client.printGreeting("Hello " + greeting.get() +"!");
        }
    };
}
```

Kerangka kerja ini memanggil metode `doExecute()` ketika semua `Promise` diteruskan ke konstruktor dari `Task` menjadi siap. Untuk detail selengkapnya tentang `Task` kelas, lihat AWS SDK untuk Java dokumentasi.

Kerangka kerja ini juga mencakup kelas yang disebut `Functor` yang mewakili `Task` yang juga merupakan `Promise<T>`. `Functor` objek menjadi siap ketika `Task` selesai. Pada contoh berikut, `Functor` dibuat untuk mendapatkan pesan ucapan:

```
Promise<String> greeting = new Functor<String>() {
    @Override
    protected Promise<String> doExecute() throws Throwable {
        return client.getGreeting();
    }
};
client.printGreeting(greeting);
```

## Urutan eksekusi
<a name="details.order"></a>

Tugas menjadi memenuhi syarat untuk dieksekusi hanya ketika semua parameter yang bertipe `Promise<T>`, diteruskan ke metode atau aktivitas asinkron yang sesuai, telah siap. `Task` yang siap untuk eksekusi secara logis dipindahkan ke antrean siap. Dengan kata lain, dijadwalkan untuk eksekusi. Kelas pekerja mengeksekusi tugas dengan menerapkan kode yang Anda tulis dalam isi metode asyinkronus, atau dengan penjadwalan tugas aktivitas di Amazon Simple Workflow Service (AWS) jika ada metode aktivitas. 

Saat tugas dijalankan dan menghasilkan hasil, maka itu menyebabkan tugas lain menjadi siap dan eksekusi program terus bergerak maju. Cara kerangka kerja menjalankan tugas penting untuk memahami urutannya di mana kode asinkron Anda dijalankan. Kode yang muncul secara berurutan dalam program Anda mungkin tidak benar-benar mengeksekusi dalam urutan itu.

```
Promise<String> name = getUserName();
printHelloName(name);
printHelloWorld();
System.out.println("Hello, Amazon!");

@Asynchronous
private Promise<String> getUserName(){
	return Promise.asPromise("Bob");
}
@Asynchronous
private void printHelloName(Promise<String> name){
	System.out.println("Hello, " + name.get() + "!");
}
@Asynchronous
private void printHelloWorld(){
	System.out.println("Hello, World!");
}
```

Kode dalam daftar di atas akan mencetak berikut:

```
Hello, Amazon!
Hello, World!
Hello, Bob
```

Ini mungkin bukan apa yang Anda harapkan tetapi dapat dengan mudah dijelaskan dengan memikirkan bagaimana tugas-tugas untuk metode asinkronus dieksekusi:

1. Panggilan ke `getUserName` membuat `Task`. Mari kita sebut saja `Task1`. Karena `getUserName` tidak mengambil parameter apapun, segera `Task1` dimasukkan ke dalam antrian siap.

1. Selanjutnya, panggilan ke `printHelloName` membuat `Task` yang perlu menunggu hasil dari `getUserName`. Mari kita sebut saja `Task2`. Karena nilai yang diperlukan belum siap, `Task2` dimasukkan ke dalam daftar tunggu.

1. Kemudian tugas untuk` printHelloWorld` dibuat dan ditambahkan ke antrean siap. Mari kita sebut saja `Task3`.

1. Pernyataan `println` kemudian mencetak "Hello, Amazon\$1" ke konsol.

1. Pada titik ini, `Task1` dan `Task3` berada dalam antrean siap dan `Task2` ada di daftar tunggu.

1. Pekerja mengeksekusi `Task1`, dan hasilnya membuat `Task2` siap. `Task2` akan ditambahkan ke antrean siap di belakang `Task3`.

1. `Task3` dan `Task2` kemudian dieksekusi dalam urutan itu.

Pelaksanaan kegiatan mengikuti pola yang sama. Ketika Anda memanggil metode pada klien aktivitas, itu menciptakan `Task` yang, setelah eksekusi, menjadwalkan kegiatan di Amazon SWF.

Kerangka kerja ini bergantung pada fitur seperti generasi kode dan proxy dinamis untuk menyuntikkan logika untuk mengonversi panggilan metode ke pemanggilan aktivitas dan tugas asinkron dalam program Anda.

## Eksekusi alur kerja
<a name="details.workflow"></a>

Eksekusi implementasi alur kerja juga dikelola oleh kelas pekerja. Saat Anda memanggil metode pada klien alur kerja, itu akan memanggil Amazon SWF untuk membuat instans alur kerja. Tugas di Amazon SWF tidak boleh disamakan dengan tugas dalam kerangka kerja. Tugas di Amazon SWF adalah tugas aktivitas atau tugas keputusan. Pelaksanaan tugas aktivitas sederhana. Kelas pekerja aktivitas menerima tugas aktivitas dari Amazon SWF, memanggil metode aktivitas yang sesuai dalam pelaksanaan Anda, dan mengembalikan hasilnya ke Amazon SWF.

Eksekusi tugas keputusan lebih terlibat. Pekerja alur kerja menerima tugas keputusan dari Amazon SWF. Tugas keputusan secara efektif merupakan permintaan yang menanyakan logika alur kerja apa yang harus dilakukan selanjutnya. Tugas keputusan pertama dibuat untuk contoh alur kerja saat dimulai melalui klien alur kerja. Setelah menerima tugas keputusan ini, kerangka kerja mulai mengeksekusi kode dalam metode alur kerja dijelaskan dengan `@Execute`. Metode ini mengeksekusi logika koordinasi yang menjadwalkan kegiatan. Saat status instans alur kerja berubah—misalnya, saat aktivitas selesai—tugas keputusan lebih lanjut dijadwalkan. Pada titik ini, logika alur kerja dapat memutuskan untuk mengambil tindakan berdasarkan hasil aktivitas; misalnya, mungkin memutuskan untuk menjadwalkan aktivitas lain.

Kerangka kerja menyembunyikan semua detail ini dari developer dengan menerjemahkan tugas keputusan secara mulus ke logika alur kerja. Dari sudut pandang developer, kode terlihat seperti program biasa. Secara rahasia, kerangka kerja memetakannya ke panggilan ke Amazon SWF dan tugas keputusan menggunakan riwayat yang dikelola oleh Amazon SWF. Ketika tugas keputusan tiba, kerangka kerja memutar ulang eksekusi program memasukkan hasil kegiatan yang diselesaikan sejauh ini. Metode dan aktivitas asinkronus yang menunggu hasil ini tidak diblokir, dan eksekusi program bergerak maju.

Eksekusi contoh alur kerja pemrosesan gambar dan riwayat terkait ditampilkan dalam tabel berikut.


**Eksekusi alur kerja thumbnail**  

| Eksekusi program alur kerja | Riwayat dikelola oleh Amazon SWF  | 
| --- | --- | 
| Eksekusi awal | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  | 
| Memutar ulang | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  | 
| Memutar ulang | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  | 
| Memutar ulang | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/amazonswf/latest/awsflowguide/details.html)  | 

Ketika panggilan ke `processImage` dibuat, kerangka kerja menciptakan instans alur kerja baru di Amazon SWF. Ini adalah catatan tahan lama dari instans alur kerja yang sedang dimulai. Program ini mengeksekusi sampai panggilan ke kegiatan `downloadImage`, yang meminta Amazon SWF untuk menjadwalkan suatu kegiatan. Alur kerja mengeksekusi lebih jauh dan membuat tugas untuk kegiatan berikutnya, tetapi tidak dapat dijalankan sampai kegiatan `downloadImage` selesai; maka, episode putar ulang ini berakhir. Amazon SWF mengirimkan tugas untuk kegiatan `downloadImage` untuk dieksekusi, dan setelah selesai, catatan dibuat dalam riwayat bersama dengan hasilnya. Alur kerja sekarang siap untuk bergerak maju dan tugas keputusan dihasilkan oleh Amazon SWF. Kerangka kerja menerima tugas keputusan dan replay alur kerja memasukkan hasil gambar download seperti yang tercatat dalam riwayat. Ini membuka blokir tugas untuk `createThumbnail`, dan pelaksanaan program berlanjut lebih jauh dengan penjadwalan tugas aktivitas `createThumbnail` di Amazon SWF. Proses yang sama berulang untuk `uploadImage`. Pelaksanaan program berlanjut dengan cara ini sampai alur kerja telah memproses semua gambar dan tidak ada tugas yang tertunda. Karena tidak ada status eksekusi yang disimpan secara lokal, setiap tugas keputusan berpotensi dieksekusi pada mesin yang berbeda. Hal ini mengizinkan Anda untuk dengan mudah menulis program yang toleran kesalahan dan dapat diskalakan.

## Nondeterminisme
<a name="details.non"></a>

Karena kerangka kerja bergantung pada pemutaran ulang, penting bahwa kode orkestrasi (semua kode alur kerja dengan pengecualian implementasi aktivitas) bersifat deterministik. Misalnya, aliran kontrol dalam program Anda tidak harus bergantung pada nomor acak atau waktu saat ini. Karena hal-hal ini akan berubah di antara pemanggilan, pemutaran ulang mungkin tidak mengikuti jalur yang sama melalui logika orkestrasi. Hal ini akan menyebabkan hasil yang tidak terduga atau kesalahan. Kerangka kerja ini menyediakan `WorkflowClock` yang dapat Anda gunakan untuk mendapatkan waktu saat ini dengan cara deterministik. Lihat bagian di [Konteks Eksekusi](executioncontext.md) untuk lebih detailnya. 

**catatan**  
Pengkabelan pegas yang salah dari objek implementasi alur kerja juga dapat menyebabkan nondeterminisme. Alur kerja implementasi benas serta beans yang mereka andalkan harus berada dalam lingkup alur kerja (`WorkflowScope`). Misalnya, kabel alur kerja implementasi beans ke beans yang membuat status dan dalam konteks global akan menghasilkan perilaku tak terduga. Lihat [Integrasi Spring](test.md#test.spring) bagian untuk detail lebih lanjut.