要約
- RFC 9218 は、0 が最も急ぎで 7 が最も低い
uと、途中の断片にも価値があるかを示す Boolean のiを定義する。初期値は end-to-end のPriorityfield、後の変更は HTTP/2・HTTP/3 の hop-by-hopPRIORITY_UPDATEで運ばれる。 - 値は送信者の効用判断であって、帯域、CPU、完了順、再送順の割当ではない。response の
Priorityも「実行済み」の確認ではなく、intermediary が採用するかどうかを判断する一つの入力にすぎない。 - 運用で必要なのは、各主張と書き換え、統合規則、接続の共有範囲、queue と flow control、DATA の配分、loss・retransmission、利用者側の到達点を同じ時系列に残すことである。
画面がまだ知らない重要度
記事ページを開くと、ブラウザは head 内のフォントを最初に発見する。ヒーロー画像は responsive source の評価後に決まり、背景の計測要求は script 実行後に出る。初期段階ではフォントが文字表示を止めている。layout が進むと、大きな画像が viewport にあると判明し、進行中の要求を急がせたくなる。
ところがオリジン側では、フォントは多くの edge に保存済みで、画像だけが混雑した shield を通るかもしれない。CDN は一人のページだけでなく、同じ backend pool に集約された別利用者の応答も見ている。ブラウザ、オリジン、CDN は異なる競争集合について話している。
画像が先に終わっても、u=0 が効いたとは限らない。単なる cache hit かもしれない。フォントが先なら、更新が無視されたとも限らない。更新 frame が届く前に bytes が flow-control window に入っていた可能性がある。waterfall は結果を示すが、誰がどの入力で順番を選んだかまでは示さない。
絶対値は絶対的な命令ではない
旧 HTTP/2 の依存木は複雑で、実装間の整合も弱かった。RFC 9218 は Structured Fields Dictionary による小さな絶対値へ移る。request で u がなければ 3、i がなければ false と扱う。i=true は、全部が来る前でも一部を処理できるという性質である。
同じ urgency の non-incremental response は順番に完了させ、incremental response は帯域を分けるのが有益な場合がある。だが、これは “when possible” の助言である。二つの object が同時に u=0 を名乗ったとき、仕様は唯一の先頭を授けない。全要求を最高 urgency にすれば、比較に使える情報がなくなる。
最低の 7 は software update のような background work 向けであり、永久停止の意味ではない。split backend で strict priority を続け、低い stream が全く前進しないと、相手は connection stall と誤認して切断することがある。小さな進捗を全体に配る判断は、local scheduler が負う可用性責任である。
最初の主張と途中の訂正
Priority は request と response の双方に置ける end-to-end field である。client の初期判断を origin まで運び、origin の response 側判断を cache とともに保持できる。HTTP version が変わっても意味を運べる点が強い。
一方、要求後の訂正には PRIORITY_UPDATE を使う。HTTP/2 では 0x10、HTTP/3 では request と push を分ける 0xF0700、0xF0701 が登録されている。frame は現在の hop の peer に完全な Priority Field Value を知らせる。省略した parameter は過去値の維持ではなく default への復帰である。
CDN は client header を保存しながら、backend への hop で別の update を出せる。header 自体を置き換えれば、それ以後の受信者が見る end-to-end statement も変わる。だから一つの “effective priority” だけを記録してはいけない。client view、origin view、各 intermediary の input と output を別々に残す必要がある。
HTTP/3 では control stream の update が対象 request stream より先に届き得る。server は最新値を保持して後で適用できるが、未開通 stream の状態保存は資源を使う。RFC は local limit を認める。priority を送る自由は、受信者に無限の記憶を要求する権利ではない。
Origin は client の採点者ではない
オリジンは、client の見えない内容依存を知ることがある。フォントが全テキストを解放する、ある画像が記事の主証拠である、といった情報を response Priority で示せる。intermediary は request と response を統合できるが、RFC 9218 は唯一の merge algorithm を決めない。
response で parameter がない場合は、その client value を変える意思がないことを示す。request の欠落が default を意味するのとは違う。両方向を同じ正規化処理に通すと、正しい値を消す危険がある。
さらに、response field は acknowledgement ではない。field が返っても scheduler が使った証拠にはならず、返らなくても無視された証拠にはならない。cache から既に配信された、fairness rule が優先された、あるいは transport が詰まった、という別の説明が残る。
Urgency を比較する母集団はホップごとに変わる
edge は多数の client connection を少数の backend に coalesce し、一つの frontend を複数 origin connection に split する。そのたびに競争相手が変わる。u=1 は特定 queue 内の比較値であって、世界全体の順位ではない。
複数 tenant を一つの queue に入れるなら、client scope を証明しなければならない。RFC 9218 は、HTTP/1.1 backend が client priority を使う場合、authentication や session information などで個別 end client に限定できることを求める方向を示す。Priority value 自体には identity がない。
もし誰でも u=0 だけで共有資源を占有できるなら、hint を authorization に変えたのは CDN の設計である。逆に paid tier や background-only connection を意図的に違う扱いにすることもあり得る。その不公平は local policy として owner、尺度、限界を明示すべきで、wire signal の必然として隠してはならない。
QUIC には QUIC の判断材料がある
HTTP scheduler の決定後も、TCP や QUIC が送信可能性を決める。congestion、flow control、loss recovery、pacing が順番を変える。高 urgency の cache miss より低 urgency の hit が速いことも、backend CPU の待ちで header 自体が遅れることもある。
HTTP/3 で packet を失ったとき、低 urgency stream の lost data を再送するか、高 urgency stream の new data を先に出すかは一義的でない。RFC 9218 は transport 実装に universal rule を課さない。回復と応用価値の証拠がその層にしかないからである。
従って causal evidence には、connection/stream ID、raw field と全 update、同時に active だった work、scheduler version と quantum、flow-control/congestion state、時間区間ごとの DATA bytes、loss と retransmission、cache/backend timing、目的とした render milestone が必要になる。
「対応」は六つの動作に分けて確認する
IANA の registry は u と i、HTTP/2 setting 0x9 と frame 0x10、HTTP/3 frame values の衝突を防ぐ。registry にあることは、production peer が negotiation、parse、receipt、scheduling を行った証明ではない。
nghttp2 でも application は旧 priority を使わない setting を送り、extension frame の受信を有効にし、request header または専用 API で update を出す。library に symbol があることと、稼働設定が bytes を変えたことの間には複数の段階がある。
そこで対応証明を六分割する。negotiation、exact parsing、provenance/merge、queue state、byte allocation、controlled contention 下の user outcome である。一つでも推測なら、対応という表現もその範囲に狭めるべきだ。
薄い合意が守るもの
RFC 9218 は Heng Lu の Minimum Initial Specification の好例として読める。共通部分は二つの parameter、dictionary、end-to-end field、version-specific update に絞られる。fairness、cache、backend mapping、transport recovery は Localized Future Decision として実装者に残る。
それは無秩序ではない。選択を観測可能にし、canary で再現し、失敗時に戻せることが条件になる。Voluntary Adoption は文書への賛同ではなく実際の negotiation と behavior で測る。Running-Code Primacy は、主張から queue、bytes、利用者結果までの連鎖を要求する。
その連鎖がなければ、「urgent」は希望であって、次の一バイトに対する権利ではない。
出典
- RFC 9218 — Extensible Prioritization Scheme for HTTP
- RFC 9113 — HTTP/2
- RFC 9114 — HTTP/3
- RFC 8941 — Structured Field Values for HTTP
- RFC 9111 — HTTP Caching
- IANA — HTTP Priority
- IANA — HTTP/2 Parameters
- IANA — HTTP/3 Parameters
- nghttp2 Programmer's Guide — Stream priorities
- nghttp2 —
nghttp2_submit_priority_update - Heng Lu — Running-Code Primacy
- Heng Lu — Minimum Initial Specification
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
