要約

  • RFC 5267の更新コンテキストは、最初の検索・並べ替え結果と、元コマンドのタグに結び付いた位置依存のADDTO/REMOVEFROMを受信順に適用する仕組みである。
  • 仕様はスナップショット機能がないと明記する。NOUPDATEによる拒否、CANCELUPDATE、メールボックスの選択解除、説明できない通信欠落は、いずれも連続性の根拠を失わせる。

動いた画面は、抜けていないことを証明しない

ライブ検索の説得力は表示の即応性から生まれる。到着したメッセージが差し込まれ、フラグ変更で対象外になった行が消える。その瞬間だけを見れば、一覧全体が最新だと考えたくなる。

しかしRFC 5267では、SEARCH、UID SEARCH、SORT、UID SORTにUPDATEを要求し、まず初期結果を得る。その後に届く未要求のESEARCHがADDTOとREMOVEFROMを運ぶ。correlatorに含まれるタグが、その変更を最初の検索コマンドへ戻す。変更はメールボックス一般の通知ではなく、特定の検索条件、識別子方式、並び順を保守する命令だ。

CONTEXTは、同じ検索条件が再利用されそうだというヒントにすぎない。サーバーはキャッシュや索引に利用しても、無視してもよい。しかも内部実装の違いを外部の振る舞いに出してはならない。仕様が「snapshot facilityはない」と述べる理由はここにある。クライアントが主張できるのは、保存された静止画の存在ではなく、初期点から全変更を受け取った連続した履歴である。

差分は集合ではなく、順序を持つ操作列である

ADDTOは挿入位置と結果列を、REMOVEFROMは削除開始位置と結果列を示す。SEARCH/SORTならメッセージシーケンス番号、UID版ならUIDを使う。位置を含むため、二つの操作を逆順に適用すれば別の結果になり得る。

RFC 5267は、同じESEARCH内に複数項目がある場合も含め、現れた順に処理するようクライアントへ要求する。サーバー側も、その逐次処理で要求された順序が維持されるよう生成しなければならない。イベント基盤が処理を並列化し、後でローカル時刻順に並べ直しても、プロトコル上の順序は復元できない。

監査に必要なのは、検索プログラム、UIDかシーケンス番号か、要求した順序、コマンドタグ、初期順序列、そして受信順を失わない差分記録である。活動中の更新コンテキストと同じタグを再利用すればBADになる。タグは名称ではなく、未要求応答がどの問いに属するかを確定する鍵だ。

EXISTSの後、EXPUNGEの前

シーケンス番号はメールボックス内の位置であり、expungeで意味がずれる。配送またはappendによるADDTOがシーケンス番号を含む場合、対応するEXISTSの後でなければならない。そこで初めて新しい番号が有効になる。逆にexpungeに伴うREMOVEFROMはEXPUNGEより前に送る必要がある。古い番号がまだ同じメッセージを指している間に削除を適用するためだ。

したがって、EXISTS、FETCH、ESEARCH、EXPUNGEは一つの受信順ログとして保存する必要がある。別々のキューへ流し、各サービスの時計で再構成する方法では因果関係を守れない。ESEARCHはコマンド実行中でなくても、別コマンドの途中でも、IDLE中でも到着できる。要求と完了応答だけを収集する観測系は、肝心の更新を見落とす。

検索条件中のシーケンス番号は、コマンド受信時点で評価される。後の番号変更だけを理由に通知は出ない。同じ数字を後の状態で読み直せば、それは元の検索の維持ではなく別の検索になる。

NOUPDATEを捨てると、静的結果がライブに見える

サーバーは内部上限などを理由に更新を拒否できる。その場合、対象タグを引数に持つNOUPDATEコード付きの未タグNOを返す。他のreturn optionは引き続き満たさなければならない。

つまり、初期結果が届き、コマンド自体が成功しても、継続更新だけは拒否され得る。行を保存しNOUPDATEを捨てる実装では、正しかった一時点の答えが「現在の一覧」として残る。状態は、要求済み、受理、拒否、活動中、取消済み、選択解除で終了、連続性不明を分けるべきで、「ロード完了」だけでは足りない。

仕様はクライアントごとに少なくとも一つの更新コンテキストを要求し、より多くを推奨する。一方、ソート済みコンテキストの方が高コストになり得るため、その拒否は単純な検索コンテキストの拒否を意味しない。再試行や静的表示への降格はできる。拒否を隠してはならない。

PARTIALは表示範囲であって、更新範囲ではない

PARTIALは順序列の一部分を返し、仮想スクロールに向く。ただしUPDATEは他のreturn optionと相互作用しない。UPDATEとPARTIALを併用しても、現在表示していない位置の変更が通知される。COUNT、MIN、MAXも更新対象をその要約だけに狭めない。

画面外の差分を捨てれば、次に要求する位置窓の根拠が崩れる。全コンテキストを維持しない設計は可能だが、その場合は古いコンテキストを無効化し、新しい初期結果を取得しなければならない。viewportは表現層であり、権威の境界ではない。

切れたストリームは、流れ続けても直らない

メールボックスが選択されなくなるか、元タグを指定してCANCELUPDATEを送ると更新は止まる。サーバーは資源を解放できる。再接続、再選択、同一条件の再検索は新しい観測であり、古い流れの再開ではない。

接続断だけでなく、parserの一部失敗、backpressureによる破棄、自動再接続後の古いUI状態の温存も同じ問題を起こす。一つの位置差分が欠けた可能性があれば、その後の差分は完全性を証明できない。

RFC 7162のCONDSTORE/QRESYNCは別の前提を持つ再同期手段である。IDLEは未要求応答を受けやすくし、NOTIFYはイベントへの関心を示す。対応能力があるだけで、欠けたCONTEXT履歴が自動修復されるわけではない。実際に手順を実行し、結果を検証し、新しい基線を確立する必要がある。

Running-Code Primacyの観点では、管理対象は「ライブ検索」という製品名ではない。実際のコマンド、能力世代、選択メールボックス、初期結果、順序付き差分、終了境界である。初期観測、UPDATE受理、再構成状態、表示ページ、利用者の行動は別々の現実層に属する。表示行からタグと因果順序へ戻れないなら、そこにあるのは現在性の証拠ではなく、動く表現である。

出典