摘要
- RFC 5267 把持续更新的搜索或排序定义成“初始答案 + ADDTO/REMOVEFROM 有序变更流”;这些变更带位置含义,并通过原命令标签归属到同一个上下文。
- 规范明确说它不提供快照机制。服务器可用 NOUPDATE 拒绝持续更新,CANCELUPDATE、邮箱取消选中、断线或无法解释的传输缺口都会终止连续性。
“还在动”不等于“没有漏”
实时界面最容易制造一种错觉:只要它刚刚动过,就一定掌握了现在。新邮件出现,旗标变化后某行消失,计数也跟着更新;屏幕把这些动作压成一个平滑的“实时搜索”。但平滑只证明渲染层收到过变化,不能证明此前每一个变化都完整到达。
RFC 5267 允许 SEARCH、UID SEARCH、SORT 或 UID SORT 请求 UPDATE。服务器先给出初始结果,之后通过 unsolicited ESEARCH 发送 ADDTO 与 REMOVEFROM。响应中的 correlator 指回创建上下文的原命令标签。每一条变更都是对那次具体查询、标识符模式和排序方式的维护指令,不是可以随意搬到相似列表上的通用事件。
规范对边界说得很直白:不存在 snapshot facility。CONTEXT 只是一项提示,服务器可以据此维护缓存或索引,也可以忽略;有没有内部缓存,不得改变外部行为。因此客户端能证明的不是“服务器替我保存着一张照片”,而是“我保存了起点,而且没有漏掉此后的任何合法补丁”。
ADDTO 与 REMOVEFROM 是位置敏感的补丁语言
ADDTO 给出上下文位置以及应插入的结果;REMOVEFROM 给出位置以及从那里移出的结果。普通 SEARCH/SORT 使用消息序号,UID 版本使用 UID。这里的“位置”使操作顺序成为语义的一部分。
RFC 5267 要求客户端严格按出现顺序处理 ADDTO 和 REMOVEFROM,包括同一 ESEARCH 响应内的多项;服务器也必须生成能按此顺序维持请求排序的补丁。先删后插与先插后删可能产生不同列表。把这些消息并行投递,再按本地时间戳排序写回,并不能恢复协议规定的顺序。
最低限度的审计对象应包括:完整查询、UID 或序号模式、请求的排序、原命令标签、初始有序结果,以及单调保存的接收次序。活动上下文的标签不能拿来创建另一个更新上下文,否则服务器应返回 BAD。标签不是装饰,它是 unsolicited 变更能够归因到正确问题的键。
EXISTS 与 EXPUNGE 划定序号的有效时刻
消息序号会因 expunge 而重排。若新投递或 append 造成带序号的 ADDTO,服务器必须先发送 EXISTS,之后那些新序号才有效。若 expunge 造成带序号的 REMOVEFROM,服务器必须在 EXPUNGE 之前发送它,因为旧序号只有那时还保留原义。
所以 EXISTS、FETCH、ESEARCH 与 EXPUNGE 必须进入同一条接收顺序日志。将它们分送不同队列,再靠各服务的墙上时钟拼回去,会丢掉因果约束。ESEARCH 还可以在没有命令执行时、处理别的命令时或 IDLE 期间到达;只记录成对请求与完成响应的监控方式,恰好会漏掉维护上下文的 unsolicited 数据。
查询条件本身若使用消息序号,也有独立边界:这些序号在服务器收到命令时求值。以后重排导致同一个数字指向别的消息,不会仅因此发出更新。拿旧查询文本在新邮箱状态上重新解释,是另一次查询,不是旧上下文的延续。
NOUPDATE:结果有效,持续承诺却不存在
服务器可能因内部上下文达到上限而拒绝更新。它会发送未标记的 NO,并以 NOUPDATE 和原搜索标签说明拒绝对象;其他 return options 仍必须得到满足。
这会形成一个很危险、却完全合规的状态:初始搜索结果可用,命令也能正常结束,但服务器没有接受持续维护。如果解析器保留结果行、丢掉 NOUPDATE,静态答案就会穿上“实时”外衣。
规范要求每个客户端至少可获得一个更新上下文,并建议提供更多;它也承认维护已排序上下文通常更昂贵,因此 SORT 被拒不表示普通 SEARCH 也必然被拒。客户端可以降级、重试或改成静态显示,却不能掩盖拒绝。运行状态至少应区分请求、接受、拒绝、活动、取消、因取消选择而结束,以及连续性未知。
PARTIAL 只裁剪画面,不裁剪更新责任
PARTIAL 返回有序结果中的一个位置窗口,很适合虚拟列表。但 UPDATE 与其他 return option 不相互限制。UPDATE 和 PARTIAL 同时使用时,服务器仍可能通知当前窗口之外的匹配变化;MIN、MAX、COUNT 也不会把更新范围缩成一个摘要值。
若前端只维护屏幕上几十行,并丢弃“暂时看不到”的补丁,下一次窗口位置就失去了依据。系统可以选择不保存完整上下文,但那就必须宣布上下文失效并重新取得基线。可视窗口只是投影,不是权威边界。
连续性终止后,后续消息不能自行补洞
邮箱不再选中,或客户端针对原标签发送 CANCELUPDATE,更新便停止,服务器也可以释放资源。重连、重新 SELECT、用相同条件再搜一次,产生的是新观察,不会复活旧流。
显式断线容易发现;更危险的是解析器漏掉一项、背压队列丢消息,或自动重连后继续沿用旧组件状态。只要有一个位置补丁可能缺失,后来收到再多补丁也不能证明列表已恢复。位置流不会因为继续流动就自愈。
RFC 7162 的 CONDSTORE/QRESYNC 提供另一套带前提的重新同步机制;IDLE 便于接收 unsolicited response;NOTIFY 表达事件兴趣。它们都不会仅凭“服务器支持”自动修补破损的 RFC 5267 上下文。客户端必须真正执行对应流程、验证结果并建立新基线。
按照 Running-Code Primacy,应受管理的不是“实时搜索”这个产品名,而是实际运行的命令、能力代际、选中邮箱、初始结果、有序补丁和终止边界。初始观察、UPDATE 获准、重建列表、可视页面与用户动作属于不同现实层。只有当每一行都能反查到上下文标签、标识符模式和接收次序时,界面才有可逆的证据;否则它只是流畅的画面。
来源
- RFC 5267:Contexts for IMAP4
- RFC Editor 的 RFC 5267 记录
- IETF Datatracker 的 RFC 5267 记录
- RFC 5267 勘误检索
- RFC 3501:IMAP4rev1
- RFC 4731:ESEARCH 扩展
- RFC 5256:SORT 与 THREAD
- RFC 2177:IDLE 命令
- RFC 5465:NOTIFY 扩展
- RFC 7162:CONDSTORE 与 QRESYNC
- RFC 5182:SEARCHRES 扩展
- IANA IMAP 能力注册表
- Lu Heng:Running-Code Primacy
- Lu Heng:On Reality Layers
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
