コメントの修正なのでたいした変更でもないのだけど、記念に記事を書いておく
net/http
の TimeoutHandler
周りを眺めているとこの記述に引っかかった。
TimeoutHandler supports the Flusher and Pusher interfaces but does not support the Hijacker interface.
以前、 TimeoutHandler
を使いつつ、少しでも速くクライアントへレスポンスを返したくて、先にレスポンスを返してそのあとログを書いたり後処理をするというコードを書こうとして、このあたりを調べた記憶があった。へーこの前はできなかったのにできるようになったのか、と思って眺めたものの Flush()
メソッドが見つからない。ちょっとコードを書いて type assertion してみても ok ではない。
git log -p src/net/http/server.go
を読んでいく
- net/http: make TimeoutHandler's ResponseWriter implement Pusher · golang/go@2889332 · GitHub
- ここで Pusher & Flusher をサポートして
- net/http: change TimeoutHandler's docs to match its new interfaces · golang/go@f3e3b71 · GitHub
- ここでその旨のコメントが追加されて
- net/http, doc/go1.13.html: revert TimeoutHandler.Flush · golang/go@4faf8a8 · GitHub
- で Flusher が revert されている
この revert のきっかけになった issue にあるように、Flush()
すると単に TimeoutHandler
のラップしている ResponseWriter
の Flush()
を呼ぶだけで、設定したステータスコードは無視されるし、タイムアウトしても 503 が書かれない(response.WriteHeader
が複数回呼ばれた警告が出る)。
しかも TimeoutHandler
は内部でバッファを持っていて ServeHTTP
の終了を待って ResponseWriter
にコピーする実装なので、Flush()
を呼んでも期待するようにクライアントへレスポンスが Flush
されるわけではない。Header と Body はひと組で扱うものなのに、Flush()
呼べたら Flush するという従来の挙動は乱暴だしいかにもうまくいかなそう。
https://github.com/golang/go/blob/go1.13.3/src/net/http/server.go#L3237
ということで、TimeoutHandler.Flush()
は revert されてしまったけど、コメントはそのまま残っていた。
PR 作る
すわプルリクチャンス、コメントなおすだけで golang のリポジトリに名前載せられるぞと思ってトライした。
Contribution Guide を読んで言う通りにする。
Google アカウントで Contributor License Agreement に同意したり、Gerrit にアカウントを作る。Gerrit よくわからないので、普段親しんでいる Github で PR を作って送る。
とにかくレビューしやすいように、ISSUE_TEMPLATE を埋めながら、上に挙げたようなタイムラインを示して、Playground に再現コードを書いて、issue を立てる。コミットログを漁って空気を読んだコミットメッセージを書いて、Fork したリポジトリへコミットして Pull-Request を作っておくる。PR のテンプレートにもいろいろドキュメントがあるのでそのとおりにする。同名のリポジトリの issue を参照する場合、Fixes golang#35161
のように {user_or_org}#{issue_num}
で参照できるの知らなかった。
PR を送ったらあとは bot が Gerrit へ同期してくれる。https://go-review.googlesource.com/c/go/+/203478/
特に指摘もなく、寝ているうちにマージされていた。めでたしめでたし。
従来は Gerrit のワークフローで敷居が高かったけど、Github になってだいぶ簡単になったみたい。Contribution Guide にあるように、マージされると間のコミットは squash され、Pull-Request の Title と Description が最終的な1つのコミットメッセージになる。