构建

不发问的画面 — 钉在墙上的东西不该发问

作者: makemind · 2026年7月20日

门外的队结尾我们写过这样一段。

没有推送。 柜台一叫、门口跟着变,这是真的,但那是因为测试装置把同一份状态塞进了两个运行时。这个样例没有做那件事。

这一篇来做。

拿在手上的画面和挂在墙上的画面

到目前为止的样例全都是靠才知道的。画面调用工具、拿到答案、画出来。

拿在手上的画面可以这样。人按下去的那一刻,就是该问的那一刻。

钉在墙上的画面不一样。 没有人会去按后厨的显示屏。于是它只会变成两者之一。

  • 不停地问 — 每秒问一次,一天就是 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