Lompat ke konten Lompat ke sidebar Lompat ke footer

Golang Concurrency #16

 Berikut adalah contoh lain yang menggabungkan concurrency dengan mekanisme pembatalan menggunakan context. Dalam contoh ini, beberapa goroutine menjalankan tugas yang membutuhkan waktu, namun jika tugas tidak selesai dalam waktu tertentu, context akan membatalkannya.


Contoh: Tugas Long-Running dengan Context Cancellation

package main import ( "context" "fmt" "time" ) // longRunningTask mensimulasikan tugas yang memerlukan waktu. // Jika tugas selesai sebelum timeout, hasilnya dikirim ke channel results. // Jika tidak, context akan membatalkan tugas tersebut. func longRunningTask(ctx context.Context, id int, results chan<- string) { select { case <-time.After(3 * time.Second): // Tugas selesai setelah 3 detik. results <- fmt.Sprintf("Task %d selesai", id) case <-ctx.Done(): // Context dibatalkan (timeout atau cancellation). results <- fmt.Sprintf("Task %d dibatalkan: %v", id, ctx.Err()) } } func main() { // Membuat context dengan timeout 2 detik. ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // Channel untuk mengumpulkan hasil. results := make(chan string, 3) // Menjalankan 3 tugas secara concurrent. for i := 1; i <= 3; i++ { go longRunningTask(ctx, i, results) } // Mengumpulkan dan menampilkan hasil dari ketiga tugas. for i := 0; i < 3; i++ { fmt.Println(<-results) } }

Penjelasan Mekanismenya:

  1. Pembuatan Context dengan Timeout:

    • Di main(), kita membuat sebuah context dengan timeout 2 detik:
      ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel()
      Ini artinya, context akan otomatis dibatalkan jika tugas-tugas tidak selesai dalam 2 detik.
  2. Menjalankan Tugas dalam Goroutine:

    • Fungsi longRunningTask dijalankan di goroutine untuk setiap tugas.
    • Setiap tugas menggunakan select untuk menunggu salah satu dari dua kondisi:
      • Selesai Tugas:
        case <-time.After(3 * time.Second) mensimulasikan tugas yang selesai setelah 3 detik.
      • Pembatalan Context:
        case <-ctx.Done() akan aktif jika context dibatalkan (misalnya karena timeout).
  3. Mekanisme Blocking dan Concurrency:

    • Masing-masing tugas berjalan secara concurrent di goroutine-nya sendiri.
    • Jika sebuah tugas tidak selesai dalam waktu 2 detik, maka ctx.Done() aktif dan tugas tersebut mengirimkan pesan bahwa tugas dibatalkan.
    • Goroutine utama kemudian membaca hasil dari channel results. Operasi membaca ini bersifat blocking, tetapi karena kita tahu ada 3 tugas, kita membaca 3 hasil.
  4. Hasil yang Diharapkan:

    • Karena setiap tugas memerlukan 3 detik untuk selesai, namun context timeout hanya 2 detik, maka semua tugas akan dibatalkan.
    • Output yang dihasilkan kira-kira akan seperti:
      Task 1 dibatalkan: context deadline exceeded Task 2 dibatalkan: context deadline exceeded Task 3 dibatalkan: context deadline exceeded

Keuntungan Pendekatan Ini:

  • Pengendalian Waktu Eksekusi:
    Dengan context timeout, kamu bisa mencegah tugas berjalan terlalu lama dan melakukan pembatalan secara otomatis.

  • Concurrency yang Terkelola:
    Tugas-tugas dijalankan secara concurrent, sehingga memanfaatkan sumber daya secara optimal, namun tetap bisa dikendalikan melalui context.

  • Responsif:
    Jika ada tugas yang selesai lebih cepat, hasilnya bisa segera diambil. Jika tidak, sistem secara otomatis membatalkan tugas yang melebihi batas waktu.

Contoh ini merupakan pola yang berguna dalam situasi di mana tugas-tugas asynchronous harus memiliki batas waktu eksekusi, seperti request HTTP, pemrosesan data, atau operasi I/O lainnya. Jika ada pertanyaan lebih lanjut atau ingin contoh lain, silakan ditanyakan!