作業を始める入口が一つなら、意図がどこへ着地するかは迷いません。分かれ始めるのは、手元から始める入口と、待ち行列へ積む入口と、すでに開いている作業へ次の入力を足す入口が、同時にあるときです。それぞれが宛先を自分で決めると、同じ意図が別の機械に着地します。応答が届かなかった再送は、二本目の実行になります。機械が沈黙していると、空いている別の機械へ移したくなります。移した先には、置いてある作業の文脈がありません。

この構成では、未終了の開始許可は、同じ場所を使う作業面につき一つです。宛先は投入したときに許可へ書き、沈黙しているあいだは別の機械へ移しません。

課題

困り始めるのは、開始が「実行した」という事実になる前に、入口が複数あるときです。

手元の操作は、人が見ている機械で始めようとします。待ち行列は、積んだときに見えていた機械へ届けようとします。古い取得の経路が残っていると、それも同じ作業の所有者になろうとします。三者が別々に成功すると、同じ作業面で実行が二つになります。ファイルも、作業の続きも、分かれます。

応答が落ちたとき、呼び出し側は同じ開始をやり直します。サーバが一つ目を許可したあとに応答だけが失われると、やり直しは新しい開始に見えます。許可を記憶していないと、二つ目を出してしまいます。記憶していても、中身が違う依頼を同じ識別子で受け付けると、前の許可の再送と、別の意図が区別できません。

宛先を、取りに来たときに決める方式は、沈黙に弱いです。生きている機械が取得した者勝ちになります。人が選んだ機械と、実際に走った機械が違います。沈黙は、その機械が死んだことと同じではありません。眠っているだけ、ネットワークが止まっているだけ、のどちらでも、外からは同じ静けさに見えます。静けさを理由に移すと、戻ってきた機械の上の作業と、移した先の作業が両方残ります。

許可を人につき一つにすると、別の場所の作業まで止まります。機械につき一つにすると、同じディレクトリを使う二つの作業が互いを見ません。一つにする単位を誤ると、拒否が多すぎるか、所有者が二人になります。

配置は、許可のあとでも変わります。置き場が変わり、作業の所属が変わります。開いている許可の宛先をその場で書き換えると、走っている側は古い場所のまま、許可だけが新しい場所を名乗ります。黙って揃えたことになり、どちらが真かが残りません。

機械の行を消したときに許可も消すと、不確実な実行の記録が消えます。遅れて届いた同じ依頼は、一つ目が無かったことになり、二本目の許可を得られます。

短い期限で付随の資格を切ることと、作業面の所有者を解放することは、別の操作です。期限だけを見ていると、付随の資格が切れた機械から、別の機械が同じ面を取りに行けます。

制約

この構成が置いた制約は、次のとおりです。

未終了の開始許可は、作業面につき一つだけ置けます。終わった許可は履歴として残り、次の開始を妨げません。開いている許可は、機械と場所を必ず持ちます。場所の無い開いた許可は作れません。

同じ依頼の識別子、同じ試行、同じ中身のダイジェストは、同じ許可の再送です。中身が違えば衝突であり、新しい許可ではありません。応答を落とした再送は、所有者を増やしません。再送のときも、してよいことの評価はやり直します。許可の行が残っていることは、権限が今も有効であることの代わりになりません。

宛先は、投入したときの配置です。機械、場所、その配置の世代を、許可に書きます。開始の時点で配置が変わっていたら拒否します。開いている許可の宛先は、別の機械へ書き換えません。

沈黙は移動の条件にしません。付随の資格は短く切れてよいです。切れても、作業面の所有者は解放しません。解放するのは、開始が終わったと記録したときだけです。長く届かない未実行の依頼は、別の機械へ渡さず、期限切れとして残します。半日より古いものは、その機械が次に取りに来たときに期限切れになります。

待ち行列の行は、積んだときに宛先を名乗ります。取得は、その宛先が、今取りに来ている機械のものであることだけを確認します。空いている機械を探しません。

古い取得の経路が残っているあいだは、同じ作業の行をロックし、未終了の許可がある面では古い経路が所有者になれないようにします。どちらの経路も、相手の確定を待たずに所有者を名乗れません。

人の入力は、許可が受理されるまで手元に残します。拒否された入力は、送られなかったものとして残ります。

機械の行や作業の行を消しても、不確実な許可は消しません。消すと、遅れた依頼が二本目を得られます。

採らなかった方式

入口ごとに始める

手元は手元で実行を開き、待ち行列は取得した機械で開き、開いている作業への送信はその接続の先で開く方式です。それぞれが成功を自分で覚え、あとからサーバが突き合わせます。突き合わせの前に、同じ意図が二つの場所でファイルを書き始めます。

入口を操作の並びの上で一つにしても、別の経路が残っていると同じことが起きます。一つの開始許可は、操作の並びの制約ではなく、未終了の行を一つしか置けないことです。

取得のときに宛先を決める

積むときには機械を書かず、取りに来た機械の中から選ぶ方式です。生きている機械が勝ちます。沈黙している機械は、選ばれません。人が見ていた場所と、実行が走った場所が違います。取得の処理が経路の選択を持つと、選択の規則と、人が固定した宛先が、別の真実になります。

この構成では、取得は選択をしません。行に書いてある宛先が、取りに来た機械のものでなければ、その機械は取れません。

沈黙を期限切れにして空ける

付随の資格が切れたら、作業面の所有者も解放する方式です。遅い機械と、死んだ機械が、外からは同じに見えます。解放した瞬間に別の機械が許可を得ると、戻ってきた機械の続きと、新しい機械の開始が両方あります。

付随の資格が短いのは、実行に渡す権限を長く持たせないためです。所有者の解放は、開始が終わった記録だけが行います。半日を超えても取りに来ない未実行は、移動ではなく期限切れです。期限切れは、その機械の上の事実として残ります。

許可を人につき一つにする

人が同時に始められる作業を一つにする方式です。関係の無い場所の作業まで止まります。逆に、機械につき一つにすると、同じディレクトリを使う作業が互いの存在を見ません。

この構成が一つにしたのは、実行が同じ場所を使う作業面です。同じ場所を使ってよい別の作業は、面の鍵を分けます。分け忘れると、方針が許す開始まで拒否されます。広くしすぎると、所有者が二人になります。索引は、その鍵の上で未終了を一つにしています。

応答が落ちたら新しい許可を出す

一つ目の応答が呼び出し側に届かなかったとき、サーバが新しい許可を作る方式です。呼び出し側は同じ依頼のつもりで、サーバは二本目を始めます。

同じ識別子と試行は、先に行をロックしてから見ます。行があれば、ダイジェストが一致するときだけ、その許可を返します。一致しなければ衝突です。返る付随の資格は、その時点の評価で作り直します。所有者の行は増やしません。

機械を消すと許可も消す

機械の行を削除したとき、開始許可を一緒に消す方式です。実行がどう終わったかが見えなくなり、遅れて届いた同じ依頼は、許可が無かったものとして二本目を得られます。削除が、不明な実行を無かったことにします。

この構成では、許可は機械の行にぶら下げて消しません。不明な実行は、閉じるまで残ります。

採用した形

開始は、一つの許可を通ります。手元から始めるときも、待ち行列から取るときも、実行の前に同じ許可を求めます。

手元からの開始と、待ち行列は、一つの未終了の許可へ入る二本の矢印です。宛先は、投入したときにその許可へ書きます。書くのは、機械と、場所と、世代です。別の機械がそれを取る矢印はありません。沈黙は、宛先を動かしません。

投入したときに宛先を書く

許可を作るとき、機械、場所、配置の世代、依頼のダイジェストを一緒に書きます。世代は、場所や作業の所属が変わったことを区別するためのものです。開始の処理は、今の配置が許可に書いたものと一致するかを見ます。一致しなければ拒否します。別の機械へ書き換えて成功にはしません。

待ち行列に積むときも、同じです。行は宛先を持ってからしか、取得の対象になりません。宛先がまだ無い行は、待ち行列の外に置いたままにします。取得は、表面から、その機械の生きている場所へ辿り、取りに来た機械と一致することだけを確かめます。別の機械を候補にしません。

配置をあとから変えたときは、開いている許可を移しません。停止を依頼し、古い作業は入力を受け付けなくなります。次に始めるなら、新しい配置に対する新しい許可です。沈黙のあいだに、この書き換えは起きません。

未終了は一つ

同じ作業面の、終わっていない許可は一つしか置けません。二つ目は、すでに所有者がいる、として拒否します。終わった許可は枠を空け、履歴として残ります。

試行を重ねるときは、一つ前の試行が閉じていることを見ます。閉じていない前の許可があるあいだは、次の試行を出しません。閉じ方のうち、開始前の失敗や中断のように、もう一度始めてよいものだけが次の試行を許します。成功した実行の再送が、新しい実行になってはいけません。

古い取得の経路は、許可を作る経路と同じ行をロックします。未終了の許可があるあいだ、古い経路は所有者になれません。許可を作る側も、古い経路が先に所有者を書いたあとは、その面を取れません。

再送は同じ許可を返す

同じ識別子、同じ試行、同じダイジェストの再送は、同じ許可を返します。二本目は開きません。ダイジェストが違えば衝突であり、新しい許可ではありません。

依頼の識別子と試行で、先にロックします。行が無く、配置が一致し、所有者が空なら、許可を書きます。行があり、ダイジェストが一致するなら、その行を返します。ダイジェストが違うなら衝突です。取り消されたあとの再送は、受理しません。

受理の応答に載せる、実行へ渡す付随の資格は、再送のときも作り直します。所属や方針が変わっていれば、古い付随の資格をそのまま渡しません。所有者の行は、その確認が成功するまで確定させません。確認が失敗したら、新しい許可も、作業面を使っている印も、一緒に戻します。

付随の資格には短い期限を付けます。期限が切れても許可の行は開いたままです。機械は同じ許可で付け直します。別の機械が、期限を理由にその面を取ることはできません。

入力は、この許可を求める前に手元に残します。受理されてから実行へ渡します。拒否の理由は、許可を出した側が持ちます。機械の上だけに理由があると、どの作業がどの理由で始まれなかったかが、機械が沈黙しているあいだ見えなくなります。拒否された入力は、手元に残ります。

沈黙は、その機械の上で待つ

宛先を書いた機械が取りに来ないあいだ、行はその機械を指したままです。別の機械の取得では見えません。半日より古い未実行は、その機械が次に取りに来たとき、期限切れとして記録します。記録は残し、別の宛先へは書き換えません。

新しい未実行が、同じ面の古い未実行を置き換えることはあります。置き換わるのは依頼の中身であり、機械ではありません。置き換えも、積んだときの同じ宛先の上で起きます。

機械が戻ってきたときは、開いている許可の続きを見ます。許可が別の機械へ移っていることはありません。配置が変わっていたときだけ、その許可はもう開始できません。変わったことは拒否として残り、静かな移動にはしません。

終わったことの記録が、枠を空けます。開始前に失敗した、中断した、所有者を解放すると決めた、という閉じ方だけが、次の許可を可能にします。不明のまま行を消す閉じ方は、採りません。

何が解けるようになったか

入口が複数あっても、同じ作業面の未終了の開始は一つになります。手元から始めた実行と、待ち行列が届けた実行が、同時にその場所の所有者になることはありません。古い取得の経路が残っていても、開いている許可と同時には所有者になれません。

応答が落ちた再送は、同じ許可を返します。二本目の実行になりません。中身が違う依頼を同じ識別子で送ると、衝突として拒否します。再送でも、してよいことの評価は最新のものになります。

宛先は投入したときに固定されます。沈黙しているあいだ、別の機械へは移りません。半日を超えた未実行は、期限切れとしてその機械の上に残ります。配置を変えたときは、許可を書き換えず、停止と、次の新しい許可に分かれます。

機械や作業の行を消しても、不確実な許可は残ります。遅れた同じ依頼が、記録が消えたことを理由に二本目を得ることはありません。

人の入力は、受理されるまで手元に残ります。拒否は、送られなかったものとして残ります。どの作業がなぜ始まれなかったかは、許可を出した側に残ります。

開始を入口ごとの成功にすると、宛先、再送、沈黙、配置の変更が、同じ成功の上で同時に正しくいられなくなります。一つに束ねたのは、未終了の所有者だけです。それ以外は、その所有者に書いた事実として残します。