飲食店の扉の前にタブレットが一台あり、カウンターの内側にもう一台ある。二つは同じ列を見る。
これが思ったより難しい。扉の前の人は客を書き入れ、カウンターの人は次の組を呼ぶ。二つの画面がそれぞれ「いま四組」と覚え始めると、カウンターが一組を座らせた瞬間に扉の前は依然として四組だ。そしてその食い違いは客との言い争いとして現れる。 待ち管理の道具を月額で売る会社が売っているものの相当部分は、実はこの食い違いを起こさない仕事だ。
サーバーひとつと画面二枚でそれを作った。
扉の前

大きな数字ひとつ、見込み時間ひとつ、一覧。扉の前の画面がやることはそれで全部だ。
一覧の「next」「1 ahead」「2 ahead」は保存されていない。 列で何番目かは一覧の順序から出てくる。
// Position is derived from the list order. Nothing stores
// "you are third" — that would be wrong the moment somebody
// ahead gives up and leaves.
'ahead': i == 0 ? 'next' : '$i ahead',
前の組が待ちきれずに帰れば、後ろの組は自動的にひとつ繰り上がる。保存していたら誰かが全部書き直さなければならない。
カウンター

#41 Han (2)。ボタンもその組の名前を抱えているカウンターの画面は同じ列を違う見方で見る。客に見せるものではないので各組がどれだけ待ったかが付く。
counter sees the same 4 parties, front of the line has waited 20 min
the same 4 parties — この行がこの記事の半分だ。二つの画面がそれぞれサーバーに尋ね、同じ答えを受け取った。
呼ぶ
カウンターでボタンを押すと先頭の組が座る。

#42 Oduya (4) に移り、THIS SHIFT は着席 1・平均待ち 20 min・現在の案内 27 minここで二つのことが同時に起きる。一覧からは抜け、記録には残る。
// The party leaves the waiting list but not the record. An owner who
// wants to know how long people actually waited has to be able to ask
// afterwards, and a deleted row cannot answer.
p.calledAtNote = 'waited ${_now - p.joinedAtMinute} min';
_served.add(p);
画面の下の seated today: 1 — Han waited 20 min がその記録だ。店主が「うちの平均待ちはどれくらいだ」と尋ねた瞬間に必要なのがこれであり、消した行は答えられない。
そして誰も触っていない扉の前

この画面は誰も触っていない。 カウンターでボタンを一度押しただけだ。
door reads: 4 parties, 11 people, about 36 min
counter called: called Han (41) — Han waited 20 min
door now reads: 3 parties, about 27 min — nobody edited this screen
estimate 36 min -> 27 min because the list is 4 -> 3
36分が27分になったのは誰かが27を書き入れたからではない。一覧が四から三になり、見込み時間は一覧から計算されるからだ。
// The estimate the person at the door reads out loud.
'estimate': '${_waiting.length * _minutesPerTable} min',
_minutesPerTable は9だ。店主が一生に一度変えるかどうかの数字であり、だからその数字だけが一か所にある。