実装

問わない画面 — 壁に掛かったものは問うてはいけない

著者: makemind · 2026年7月20日

扉の前の列の末尾にこう書いた。

プッシュがない。 カウンターが呼べば扉の前が追いかけたのは事実だが、それはハーネスが二つのランタイムに同じ状態を入れてやったからだ。このサンプルはそれをやっていない。

この編がそれをやる。

手に持つ画面と壁に掛かった画面

これまでのサンプルはすべて問うて知った。画面が道具を呼び、答えを受け取り、描く。

手に持っている画面はそれでいい。人が押す瞬間がそのまま問う瞬間だからだ。

壁に打ち付けた画面は違う。 厨房のディスプレイを押す人はいない。すると二つのうちどちらかになる。

  • 問い続ける — 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だ。 三件が届く間、画面は何も問わなかった。

SUBSCRIBED — 3 to make. #71 Bibimbap / #72 Cold noodles / #73 Pork cutlet. made 0 · waiting 3
SUBSCRIBED — 3 to make. #71 Bibimbap / #72 Cold noodles / #73 Pork cutlet. made 0 · waiting 3

検証がその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

このコンテンツは開発者以上が必要です

サインインしてプランをアップグレードすると続きを読めます。

プランを見る
Twitter