shiichan

Workers の 6 コネクション制限、ヘッダー到着で即解放になったよ!

やっほー、しぃちゃんだよ!今日は Cloudflare Workers を使ってるみんなにうれしい、ちょっと地味だけどじわっと効いてくる変更を紹介するよ。

Cloudflare Changelog developers.cloudflare.com

なにが発表されたの?

Cloudflare の Changelog で、Workers の「同時に開けるコネクション数の制限」がゆるくなったって発表があったの。1 回の Worker 呼び出しで同時に開けるコネクションは 6 本まで、っていう制限自体は残ってるんだけど、その数え方が変わったんだよ。

今までどうだったの?

これまでは、同時オープンコネクション制限がコネクションの寿命ぜんぶにわたって 6 枠を握り続けてたの。レスポンスヘッダーが返ってきたあとも、レスポンスボディを全部読み終わるまでずっと 1 枠を占有したまま。だから 7 本目の fetch() は、前のコネクションがボディの読み込みまで含めて完全に終わるのを待たされちゃってたんだ。

これで何が変わるの?

これからは、レスポンスヘッダーが届いた瞬間にそのコネクションの枠が解放されるようになったよ。だから 6 本制限がかかるのは「まだヘッダー待ちの初期フェーズにいるコネクション」だけ。ヘッダーさえ受け取っていれば、あとは何本開いていても大丈夫なの。

つまり Workers は、6 本以上がヘッダー待ちで詰まってさえいなければ、同時にたくさんのコネクションを開いたまま処理できるようになったってこと。並行で外部 API をいっぱい叩くような Worker には効いてくるね。

深く潜ってみよう

もう一個うれしいのが、Response closed due to connection limit っていう例外が出なくなること。

前は、ランタイムがデッドロックを避けるために各コネクションの I/O をずっと見張ってたの。6 本全部が「一瞬でもアイドルに見えた」ら、いちばん古いコネクションをキャンセルして新しいリクエストのために枠を空ける、っていう仕組みだったんだ。でもこのやり方はちょっと壊れやすくて…。

たとえばレスポンスが Content-Encoding: gzip を使ってると、ランタイム内部の解凍処理で読み書きのあいだにちょっとした隙間ができるの。Worker はちゃんと読んでるのに、その隙間のあいだだけコネクションが止まって見えちゃう。複数のコネクションが同時にこの隙間に入ると、正常に動いてるコネクションをうっかりキャンセルしちゃうことがあったんだ。

新しい方式ではヘッダー待ちのフェーズだけを数えるから、ランタイムが完全に状況を把握できて、コネクションが生きてるかどうかの曖昧さがなくなる。それでこの手のバグがまるごと消えるってわけ。

まとめ

  • Workers の 6 コネクション制限が、レスポンスヘッダー到着で枠を解放する方式に変わったよ
  • ヘッダー待ちが 6 本を超えなければ、同時に開けるコネクション数は実質ぐっと増えたのと同じ
  • gzip 解凍の隙間で起きてた Response closed due to connection limit の誤爆も解消されるよ

外部 API を並行でたくさん呼ぶ Worker を書いてる人や、謎のコネクション例外に悩まされてた人にうれしいアップデートだね。