Membuat Retry Task di Golang

Gilang Prambudi
3 min readJan 17, 2023

--

Komponen helper penting yang perlu ada disetiap skeleton project kita untuk menghandle ulang proses yang gagal / belum siap.

Pernah gak kalian mencoba integrasi ke API pihak ketiga, namun diperlukan proses recheck karena hasil yang diinginkan masih dalam proses atau perlu dicheck ulang dalam beberapa waktu kedepan?

Semisal seperti skenario berikut:

“Terdapat 2 API, Payment & Order Status Inquiry, setelah proses payment selesai, maka kita perlu mengecek status order nya, namun kadang walau proses payment berhasil, status order tidak ter-update secara real-time, sehingga kita perlu melakukan proses recheck selama beberapa detik kedepan”

Kalau digambarkan dengan sequence diagram, maka akan seperti ini gambarannya:

Terlihat ketika proses Order Status Inquiry di atas, terdapat proses looping yang akan berjalan sampai status order dinyatakan berhasil. Ada beberapa cara untuk menghandle proses ini, antara lain:

  1. Membuat blocking-loop secara infinite dalam thread yang sama hingga OrderStatus berubah dari Pending
  2. Membuat blocking-loop secara finite dalam rentang waktu dan percobaan tertentu dalam thread yang sama hingga OrderStatus berubah dari Pending, ketika habis, maka akan ada opsi recheck manual
  3. Membuat non-blocking-loop secara asynchronous dalam rentang waktu dan percobaan yang dikonfigurasi dalam thread yang berbeda untuk melakukan proses dedicated dalam pengecekan OrderStatus

Tentu proses ini dapat dilakukan dengan berbagai cara, namun, pada artikel ini, saya akan tunjukkan salah satu cara paling efektif serta aman dalam melakukan proses ini, dengan pendekatan pada poin 3 menggunakan konsep Retry Task.

Sebenarnya apa sih keuntungannya menggunakan Retry Task dengan pendekatan poin no. 3 tersebut? Berikut breakdown nya:

  1. Proses dilakukan asynchronous, sehingga tidak membuat proses lain yang perlu dilakukan setelah API Payment ter-block, di skenario ini bisa saja sistem melakukan proses lain seperti mengirim email invoice atau memasukkan data analitik ke database tanpa perlu menunggu proses Order Inquiry selesai
  2. Dengan adanya dedicated proses diluar dari thread utama, membuat kode menjadi lebih clean dan memiliki responsibility yang jelas, logika penjadwalan dilakukan pada wrapper yang terdapat di komponen Retry Task sehingga lebih mudah di-maintain
  3. error-handling yang lebih mudah, karena ketika terjadi error, tidak akan berdampak pada banyak dependency lain dalam flow utama

Lalu, mari kita implementasikan Retry Task ini ke dalam code Golang

Buat Package Retry Task

Implementasi Scheduler & Retry

pada function Execute(…), dilakukan proses retry task berdasarkan konfigurasi delay dan retry yang telah diinisiasi pada fungsi InitiateConfig(…). Proses ini akan berjalan secara berulang dalam rentang waktu tertentu, namun dapat dihentikan ditengah jalan dengan memanggil fungsi StopRetryTask(ctx context.Context) di dalam implementasi taskFunc.Exec(…).

Test kedalam code

Dapat dilihat pada line 57, terdapat goroutine yang berfungsi untuk melakukan proses inquiry dengan implementasi Retry Task. karena proses ini bersifat asynchronous, maka proses utama dapat berlanjut.

Berikut output nya ketika dijalankan TestRetryTask_Execute(t *testing.T):

Bisa dilihat, walaupun pada konfigurasi, perulangan dilakukan sebanyak 3 kali, namun ketika perulangan kedua, OrderStatus sudah berubah menjadi SUCCESS, sehingga RetryTask dapat dihentikan menggunakan fungsi StopRetryTask(ctx) di line 37.

Kedepannya, RetryTask ini dapat di improvisasi sesuai kebutuhan pada service kalian masing-masing, contohnya:

  1. Mendaftarkan setiap RetryTask kedalam Database supaya dapat dimonitor dan dikontrol lewat dashboardnya sendiri
  2. Membuat konfigurasi penjadwalan menggunakan cron-job sehingga lebih fleksibel

Kesimpulan

Dalam membuat program, kita perlu memperhatikan bagaimana setiap komponen dipisahkan dan memiliki tanggung-jawabnya masing-masing. Sebisa mungkin perlu kita membuat kode yang ditulis memiliki kohesi yang tinggi namun dengan coupling yang rendah.

High cohesion adalah kondisi ketika komponen dalam sistem fokus dalam melakukan tugas tertentu atau memiliki tujuan yang jelas. Low coupling adalah kondisi di mana satu modul atau komponen dalam sistem tidak terlalu bergantung pada modul lain.

High cohesion and low coupling diharapkan dapat meningkatkan maintainability dan scalability dalam perancangan sistem.

--

--

Gilang Prambudi

I prefer old-school song and technology, as they are obvious and more understandable.