現在テスト中です: 完了後にGitHubのコードを公開する予定です。

A · 獲得

構造refresh

ロック獲得リクエストです。leaseは、クライアントがreleaseせず終了しても期限後にサーバーがkeyを回収する安全網です。waitは獲得待機の上限(秒)で、0はqueueに入らず1回だけ即時試行します。無限待機はありません。成功は獲得 A、待機失敗はタイムアウト T、queue/server capacity満杯はbusy Bです。

owner — 応答相関識別子

owner1回の獲得試行の応答を見つける識別子で、クライアントがcallごとに新しく生成します。サーバーはATBに同じ値をechoするため、pipelineされた応答を対応付けられます。

ownerはロック権限でもfencing tokenでもありません。同じkeyとownerを再送してもactive tokenは返らず、leaseも更新されません。要求byteを1つでも送った可能性があり応答を確認できなければ、同じownerで自動再送せずIndeterminateにします。critical sectionへ入ってはならず、観測できなかったgrantは遅くともlease expiryで回収されます。

公式クライアントはcallerの正規化済みwaitからmonotonicな全体deadlineを一度だけ作成し、確実に未送信のretryでもそのdeadlineとownerを維持します。writerは送信直前に残り時間を切り上げてwire waitを再計算するため、遅い接続がserverで新たな255秒の待機を始めることはありません。全体deadlineを過ぎたqueued要求は送信せず、すでに送信された可能性があれば該当sessionを閉じてIndeterminateで終了します。deadline直前に相関済みのAをTicket配信段階で遅れて発見した場合はsessionを閉じる必要はありませんが、exact tokenの補償releaseを予約してIndeterminateを返します。相関済みのTBはそれぞれ確定timeoutと確定busyのままです。

元のwait=0はwire上で引き続き即時試行です。別の5秒transport deadline内では、要求が確実に未送信の場合に限り同じownerで接続を選び直してretryでき、実際のserver-side試行は依然として正確に1回です。送信された可能性が生じた後は決して再送しません。

バイト表記: opはASCII文字、wait/leaseはバイナリ(u8、ビッグエンディアン)、ownerは バイナリ(u64、ビッグエンディアン)、keyはUTF-8テキスト(可変長、構造上はNと表記)です。 末尾の\n0Aです。固定ヘッダはバイナリ値のため0x0Aを含みうるので、改行を探す前に バイト数で先に消費しなければなりません。

フロー

クライアント
サーバー
A · 獲得 (key · wait · lease · owner)
キーは未使用 → 即座に発行
A · 獲得済み (token)
使用中 → FIFOキューで順番を待つ
順番が来たら → A · 獲得済み (token)
waitを超えたら → T · タイムアウト
wait=0 + 保持中 → T · 即時未獲得
待機キューが満杯 → B · ビジー
リクエストレスポンス

キー状態ごとの動作の全ルールはリクエスト × キー状態マトリクス を参照してください。