Berurusan dengan Hilangnya Konektivitas

Setelah panggilan RPC selesai, koneksi tidak ditutup; itu ditandai sebagai gratis. Dengan demikian, server dapat mati atau konektivitas jaringan dapat hilang selama atau di antara panggilan, sementara koneksi duduk di kumpulan. Sebagai masalah kebijakan, run time RPC mencoba kembali panggilan tersebut hanya jika dua kondisi berikut terpenuhi:

  • Server mungkin tidak dapat menjalankan panggilan, atau panggilannya idempotensi.
  • Klien dapat menerapkan percobaan ulang dengan cara yang efisien performa.

Paragraf berikut memperluas dan mengklarifikasi dua kondisi tersebut.

Panggilan idempotensi adalah panggilan yang dapat dijalankan lebih dari sekali di server tanpa efek samping yang tidak diinginkan. Misalnya, memiliki panggilan RPC yang mengkueri saldo di bank untuk akun tertentu bersifat idempotensi. Jika panggilan ini dijalankan dua kali karena hilangnya konektivitas, tidak ada bahaya yang dilakukan. Contoh lain dari panggilan idempotensi adalah mengubah alamat pelanggan dalam database. Mengeksekusi dua kali tidak masalah, karena eksekusi kedua hanya mengganti alamat yang sudah ada dengan alamat yang sama. Operasi seperti "mengurangi lima puluh dolar dari akun xyz" tidak idempotensi. Hilangnya konektivitas jaringan tidak boleh mengakibatkan beberapa eksekusi panggilan tersebut.

Agar aman, run time RPC memperlakukan semua panggilan sebagai non-idempotensi. Atribut [idempotoen] tidak didukung untuk ncacn_ip_tcp, dan diabaikan. Dengan demikian, kondisi pertama dalam daftar sebelumnya dikurangi ke server yang mungkin tidak dapat menjalankan panggilan.

Dalam banyak kasus, run time RPC tidak dapat secara konklusif menentukan panggilan belum dijalankan pada server. Dalam kasus seperti itu, klien tidak akan mencoba lagi menjalankan panggilan.

Contoh berikut mengilustrasikan kapan run time RPC melakukan atau tidak mencoba kembali panggilan:

  • Server di-boot ulang.

    Panggilan RPC sederhana tanpa keamanan dilakukan pada antarmuka di mana tidak ada panggilan sebelumnya yang dilakukan setelah boot ulang. Karena tidak ada panggilan yang dilakukan pada antarmuka ini, run time RPC pertama kali mencoba menegosiasikan penggunaan antarmuka. Ini mengirimkan paket menggunakan koneksi di kumpulan. Karena server di-boot ulang, dan koneksi tidak lagi valid, server mengembalikan kesalahan. Karena run time RPC sisi klien belum mulai mengirim data untuk panggilan aktual, klien menentukan bahwa server tidak mungkin telah dijalankan pada data tersebut. Oleh karena itu, ia menutup koneksi dan mencari koneksi lain di kumpulan. Jika tidak dapat menemukan koneksi, koneksi akan terbuka dan mencoba menegosiasikan penggunaan antarmuka lagi. Jika ini berhasil, panggilan dilakukan (yaitu, coba lagi dilakukan, karena kegagalan terdeteksi sebelum panggilan dimulai).

  • Panggilan RPC dengan keamanan tingkat privasi (enkripsi) dilakukan pada koneksi dengan konteks keamanan yang sudah dinegosiasikan.

    Untuk memastikan performa yang efisien, run time RPC mengenkripsi paket marshaled sebaris (melalui data teks yang jelas). Jika upaya untuk mengirim data gagal, run time RPC tidak dapat mencoba kembali panggilan, karena data teks yang jelas telah ditimpa dengan data terenkripsi, dan tidak dapat mengenkripsi ulang data dengan konteks keamanan baru. Oleh karena itu, tidak ada coba lagi yang dilakukan.

  • Pengiriman fragmen non-pertama gagal.

    Coba lagi tidak dilakukan, karena run time RPC dapat memilih untuk membuang isi fragmen pertama setelah selesai, dan tidak memiliki cara untuk mencoba kembali mengirim fragmen pertama.

  • Permintaan RPC dikirim.

    Server membatalkan koneksi. Tidak ada coba lagi yang dicoba, karena RPC tidak dapat membedakan apakah server menerima panggilan dan mulai menjalankannya.

Jika server menggunakan titik akhir dinamis, RPC tidak akan menyelesaikan kembali titik akhir selama percobaan ulang. Ini berarti bahwa jika server diturunkan dan muncul kembali, server mungkin berada di titik akhir yang berbeda, dan RPC tidak akan secara transparan menyelesaikan kembali titik akhir ketika panggilan dicoba kembali. Untuk memaksa penyelesaian ulang titik akhir, klien RPC harus memanggil RpcBindingReset sebelum mencoba kembali panggilan.

Dalam banyak kasus ini, jika klien RPC dapat menentukan apakah panggilan idempotensi, atau jika menyimpan data yang dibuang RPC, ia dapat memilih untuk membangun mekanisme coba lagi di atas RPC.

Catatan

Jika server adalah kluster, dan simpul kluster yang berbeda menjalankan versi perangkat lunak server yang berbeda, coba lagi RPC dapat melakukan panggilan pada node kluster yang berbeda dalam kasus failover, dan berpotensi pada versi server yang berbeda. Dalam skenario penyebaran tersebut, pastikan klien tidak mengandalkan versi tertentu dari perangkat lunak server untuk menjalankan panggilan tertentu. Jika ya, klien harus membangun mekanisme di atas RPC yang mendeteksi dan menangani kondisi tersebut.