Distributed lease dapat memindahkan kepemilikan tanpa menghentikan proses yang sebelumnya memegang lease tersebut. Sebuah worker dapat berhenti cukup lama hingga lease kedaluwarsa, lalu aktif kembali setelah worker lain memperoleh lease yang sama. Pada saat itu, kedua proses dapat mengeksekusi kode yang ditulis dengan asumsi bahwa kepemilikan bersifat eksklusif.
Kedaluwarsa lease menyelesaikan status kepemilikan di coordination service. Mekanisme itu tidak mencabut waktu CPU, membatalkan network request yang sedang berjalan, atau menghapus I/O yang sudah masuk buffer pada holder lama. Fencing token menutup celah tersebut dengan membawa nilai pengurutan dari keputusan kepemilikan menuju resource yang dilindungi.
Kedaluwarsa lease tidak menghentikan holder lama
Pertimbangkan worker yang memperoleh lease, membaca sebuah objek, menjalankan komputasi panjang, lalu menulis penggantinya. Lease memiliki durasi terbatas agar worker lain dapat mengambil alih setelah terjadi crash.
Takeover yang sama dapat terjadi ketika worker pertama tidak mengalami crash. Runtime pause yang panjang, scheduler yang kelebihan beban, network partition, atau request perpanjangan lease yang terlambat dapat membuat coordination service menganggap lease telah kedaluwarsa. Worker kedua kemudian memperoleh lease tersebut secara sah.
Worker pertama dapat aktif kembali setelah itu. State lokal masih mencatat bahwa lease pernah diperoleh, dan kode yang sudah melewati pemeriksaan acquisition dapat terus bergerak menuju resource yang dilindungi. Memeriksa lease kembali sebelum setiap write dapat mempersempit sebagian timing window, tetapi tidak dapat membuat pemeriksaan dan remote write menjadi atomik pada dua sistem independen.
Inilah masalah stale holder: eksklusivitas sudah berubah di coordinator, sedangkan holder terdahulu masih mampu mengirim operasi.
Token membawa urutan kepemilikan ke state resource
Skema fencing memberikan token yang meningkat secara monoton pada setiap acquisition yang berhasil. Jika worker A menerima token 41 dan owner berikutnya menerima token 42, urutannya menjadi eksplisit.
Setiap operasi yang membutuhkan kepemilikan lease membawa token tersebut ke resource yang dilindungi. Resource menyimpan token terbesar yang pernah diterima untuk ownership domain itu dan menolak operasi dengan token yang lebih kecil.
Aturan sederhananya:
if request.token < resource.highest_token:
reject request
apply request
resource.highest_token = max(resource.highest_token, request.token)Misalkan worker A berhenti setelah menerima token 41. Lease miliknya kedaluwarsa, worker B memperoleh lease dengan token 42, lalu B berhasil melakukan write. Ketika A aktif kembali dan mengirim write tertunda dengan token 41, resource menolaknya karena 41 lebih lama daripada 42.
Properti safety berasal dari enforcement pada resource. Token yang dibuat coordinator tetapi diabaikan storage system hanya menjadi metadata.
Monotonisitas lebih penting daripada wall-clock time
Fencing token merepresentasikan urutan acquisition, bukan waktu yang telah berlalu. Karena itu, sequence number lebih sesuai daripada timestamp ketika coordinator dapat mengalokasikannya secara konsisten.
Wall clock dapat berbeda antar-host dan dapat bergeser relatif satu sama lain setelah penyesuaian sinkronisasi. Bahkan clock yang tersinkronisasi rapat tidak dengan sendirinya menempatkan dua lease acquisition dalam satu urutan serial. Properti yang dibutuhkan lebih sederhana: acquisition sukses yang lebih baru harus menerima token yang lebih besar daripada setiap acquisition sukses sebelumnya dalam fencing domain yang sama.
Token tidak harus bertambah tepat satu. Lompatan nilai tidak bermasalah selama urutannya tetap ketat dan nilai tidak digunakan kembali. Database sequence, revision number berbasis consensus, atau counter terserialisasi lain dapat menyediakan pengurutan yang dibutuhkan ketika semantik terdokumentasinya sesuai dengan desain lease.
Wraparound dan penggunaan ulang token harus ditiadakan selama masa operasional domain. Representasi integer terbatas dapat digunakan hanya jika laju alokasi dan aturan reset membuat penggunaan ulang mustahil selama operasi lama masih mungkin tiba.
Resource harus membandingkan token secara atomik dengan mutasi
Memeriksa token di proses aplikasi lalu mengirim unconditional write ke storage masih menyisakan race. Owner yang lebih baru dapat melakukan write di antara pemeriksaan tersebut dan mutasi milik owner lama.
Perbandingan harus berada di titik yang melakukan serialisasi terhadap state yang dilindungi. Untuk sebuah database row, token dapat disimpan bersama data dan dimasukkan ke conditional mutation:
UPDATE account_snapshot
SET payload = :payload,
fence_token = :token
WHERE id = :id
AND fence_token < :token;Caller harus memeriksa jumlah row yang terpengaruh. Nol row dapat berarti token yang lebih baru sudah mencapai row tersebut, dengan mempertimbangkan predicate lain yang mungkin ada di statement.
Untuk object store, queue, device controller, atau external API, proteksi setara membutuhkan operasi yang dapat diurutkan oleh resource itu sendiri terhadap token. Jika interface tidak menyediakan conditional mutation atau command yang sadar token, aplikasi tidak dapat membangun atomic fencing di sekeliling remote side effect yang unconditional.
Batas ini penting. Fencing bukan sekadar fitur lock service; mekanismenya merupakan kontrak yang mencakup alokasi token dan enforcement pada resource.
Scope token harus sama dengan scope kepemilikan
Satu global counter dapat melakukan fencing untuk banyak resource, tetapi alokasi global bukan syarat. Hal yang diperlukan adalah operasi yang dapat berkonflik memiliki token yang dapat dibandingkan.
Jika lease independen untuk setiap customer, shard, atau object, setiap domain dapat memiliki monotonic sequence sendiri selama token lama tidak pernah dianggap sebagai token aktif dalam domain tersebut. Resource memerlukan identitas yang cukup di dalam request untuk mengaitkan token dengan sequence yang benar.
Menggunakan token dari domain yang tidak berhubungan seolah memiliki satu urutan dapat menghasilkan penolakan atau penerimaan yang keliru. Secara konseptual, identitasnya lebih dekat ke tuple (ownership_domain, token) daripada integer tunggal.
Masalah serupa muncul setelah destructive reset. Membuat ulang lock record dengan counter yang kembali ke nol dapat membuat owner baru tampak lebih lama daripada traffic tertunda dari generasi sebelumnya. Generation identifier atau counter yang state-nya bertahan setelah record dibuat ulang dapat mencegah ambiguitas tersebut.
Fencing tidak membuat semua side effect dapat dibatalkan
Resource hanya dapat menolak operasi usang jika operasi mencapai enforcement point sebelum efek yang tidak dapat dibatalkan terjadi. Pola ini sesuai untuk mutasi state yang mendukung conditional ordering.
Sebagian side effect tidak menyediakan batas semacam itu. Email yang sudah diserahkan ke external delivery service tidak dapat ditarik kembali oleh fencing token yang datang kemudian. Payment request yang sudah diterima third-party API tidak dapat diberi fence secara retroaktif kecuali API tersebut ikut menjalankan protokol atau menyediakan kontrak idempotency dan conditional state yang setara.
Sistem dengan efek campuran sering memisahkan fenced state transition dari pekerjaan downstream. Sebagai contoh, fenced database transaction dapat mencatat outbox entry, lalu pengiriman pesan mengikuti aturan duplicate control dan idempotency tersendiri. Fence melindungi kepemilikan state transition; proteksi itu tidak otomatis meluas ke sistem yang tidak pernah memeriksa token.
Lease dan fence menutup failure window yang berbeda
Lease tetap memiliki nilai operasional. Lease membatasi jumlah actor yang biasanya menjalankan pekerjaan, menyediakan takeover setelah kegagalan, dan dapat mengurangi eksekusi redundan. Fencing token melindungi resource ketika asumsi koordinasi tersebut untuk sementara tidak berlaku.
Pemisahan ini juga memengaruhi failure handling. Kehilangan lease semestinya menghentikan holder dari memulai pekerjaan baru, tetapi correctness tidak bergantung pada penghentian seketika jika setiap mutasi yang dilindungi menggunakan fencing. Sebaliknya, logika perpanjangan lease yang sempurna tidak dapat menggantikan resource-side fencing ketika operasi usang dapat bertahan melewati masa kepemilikan.
Kontrak gabungannya spesifik: coordinator melakukan serialisasi acquisition dan menerbitkan token yang terus meningkat; holder menyertakan token tersebut pada operasi yang dilindungi; resource secara atomik menolak operasi yang lebih lama daripada token terbesar yang sudah diterima untuk domain yang sama. Setiap bagian melindungi batas yang berbeda, dan menghilangkan enforcement terakhir tetap memberi stale writer jalur untuk mengubah state.