Fallacy #1 : The network is reliable
Kita sudah pasti dapat memastikan jawaban dari pertanyaan apakah network reliable ? Sudah pasti jawabannya adalah Tidak. Karena memang tidak ada garansi bahwa network tersebut realiable. Masalah tersebut kadang-kadang terletak pada hardware, security, software issue.
Kita sering sekali membuat code yang membuat masalah tersebut tidak terlihat. Kita membuat object proxy terhadap remote object dan memanggil method yang ada pada object tersebut.
var svc = new MyService();
var result = svc.Process(data);
Jika anda menelaah code di atas, maka anda akan sadar banyak magic yang dilakukan oleh code yang simple tersebut. Bagaimana object tersebut membuat proxy, koneksi ke remote object dsb. Serialization and Deserialization. Kita tidak memikirkan hal tersebut karena kebanyakan kita melakukan testing di local PC dan semuanya terlihat baik-baik saja. Tetapi jika kita menjalankan code tersebut di dalam network maka kita kemungkinan akan mendapatkan banyak error yang tidak terlihat jika kita menjalankan code tersebut di local PC.
Dan jika kita menjalankan code tersebut di dalam network, maka kemungkinan besar code tersebut akan berjalan dengan baik-baik saja, kecuali jika ada masalah. Dan kita tidak bisa memprediksi kapan masalah tersebut akan terjadi.
Nah, sekarang bagaimana jika pada saat remote call tersebut terjadi HTTP Timeout Exception ? Apa yang harus kita lakukan, tentu saja code kita harus dapat menangani masalah tersebut bukan ? Data bisa saja hilang atau diterima setengah atau gagal di proses di tengah dsb.
Kemungkinan server masih saja melakukan proses terhadap request tersebut. Jika server tersebut melakukan long running process atau workflow maka mungkin saja timeout terjadi sesuai dengan setting yang ada di web server. Data tidak hilang tetapi kita tidak mendapatkan response.
Kemungkinan yang lain adalah timeout terjadi ketika request ada di dalam perjalanan ke server. Data tidak sampai ke server.
Sebagai client apa yang harus kita lakukan jika menghadapi masalah tersebut ? Tentu saja tidak jelas ? Karena ada beberapa kemungkinan yang akan dihadapi dikarenakan network tersebut. Ada beberapa hal yang biasa dilakukan oleh developer yaitu melakukan logging terhadap error tersebut. Melakukan retry terhadap remote call tersebut. Atau malah yang sangat vulgar adalah memberikan error tersebut langsung ke user dari system.
Sekarang kita akan menggali solusi apa yang mungkin kita buat dalam hal ini. Salah satu solusinya adalah
Retry & Ack / Store & Forward / Transactions
Untuk syncrhonous operation kita akan melakukan Retry dan Ack. Jika kita dalam situasi asynchronous kita akan melakukan store and forward. Hal tersebut dapat menjadi kompleks jika kita melakukan remote call lebih dari satu. Transaction juga menjadi sangat tricky. ACID tersebut menjadi sangat sulit di kontrol. Jika anda melakukan solusi ini di atas HTTP maka anda akan masuk ke dalam solusi "hampir selesai". Saran saya adalah jangan sekali-kali melakukan hal tersebut. Terlalu banyak kasus-kasus yang sulit ditangani. Gunakanlah reliable messaging infrastructure seperti MSMQ, Azure Service Bus, RabbitMQ etc.
Message Queue memang di desain untuk mengatasi masalah-masalah tersebut. Tetapi tentu saja ada hal yang harus kita korbankan jika kita bergerak ke arah Message Queue atau Asyncrhonous operation. Kita tidak dapat lagi melakukan request response synchrnous dengan abstraksi method call.
Kita harus melakukan re design dari system kita untuk menangani hal tersebut dengan asynchronous operation dengan message queue. Martin Fowler mencetuskan juga law dari distributed system. Jangan distribusikan object anda. Karena masalah konektifitas.
Apakah itu REST call, RPC call atau Microservices, tetap saja anda tidak dapat lepas dari masalah-masalah yang ada tentang distributed object. Semakin banyak mesin yang terlibat dalam suatu proses remote call semakin buruk permasalahan yang akan terjadi