扉の前の列の末尾にこう書いた。
プッシュがない。 カウンターが呼べば扉の前が追いかけたのは事実だが、それはハーネスが二つのランタイムに同じ状態を入れてやったからだ。このサンプルはそれをやっていない。
この編がそれをやる。
手に持つ画面と壁に掛かった画面
これまでのサンプルはすべて問うて知った。画面が道具を呼び、答えを受け取り、描く。
手に持っている画面はそれでいい。人が押す瞬間がそのまま問う瞬間だからだ。
壁に打ち付けた画面は違う。 厨房のディスプレイを押す人はいない。すると二つのうちどちらかになる。
- 問い続ける — 1秒ごとに問えば一日8万6千回だ。そのうち意味のある答えは数百回
- 遅れる — 10秒ごとに問えば注文が最大10秒遅れて出る
どちらの選択肢も悪く、二つ目が特に悪い。 厨房で10秒は長い。
キューを道具の結果ではなくリソースに
server.addResource(
uri: _queueUri,
name: 'Kitchen queue',
description: 'Tickets the kitchen still has to make',
mimeType: 'application/json',
handler: (uri, params) async => ReadResourceResult(...),
);
そしてキューが動けばサーバーが言う。
_tickets.add(_Ticket(_next++, _incoming[i++]));
// The whole point. Nobody asked; the server says the queue moved.
server.notifyResourceUpdated(_queueUri);
画面の側は一度購読して終わりだ。
client.onResourceUpdated((uri) async { ... });
await client.subscribeResource(_queueUri);
呼び出し回数が証拠だ
この種の主張は言葉では検証できない。「プッシュでやっています」と書いておいて裏でポーリングしているコードはよくある。
だからハーネスが自分が呼んだ道具を数える。
subscribed to orders://queue — from here the screen asks for nothing
--- window opens: tool calls so far 1 ---
told: orders://queue changed (notification 1)
told: orders://queue changed (notification 2)
told: orders://queue changed (notification 3)
--- window closes ---
notifications received: 3
screen updates: 3
tool calls made by the screen inside the window: 0
0だ。 三件が届く間、画面は何も問わなかった。

検証がその0を守る。
grep -q "tool calls made by the screen inside the window: 0" captures/run.log \
|| { echo " the screen asked for something — this is polling, not push"; exit 1; }
そして画面定義にもポーリングがあってはならない。
if grep -RIqiE '"(poll|interval|refresh|timer)"' kitchen.mbd; then
echo " the screen definition is polling"; exit 1
fi