2016/03/29

Recent entries from same category

  1. バイナリ一つで zip, tar.gz, tar.bz2, tar.xz が開けるコマンド「archiver」(と go1.8 への対応方法)
  2. Golang 1.8 でやってくる database/sql の変更点
  3. GolangでAPI Clientを実装する、の続き
  4. golang で終了を確認するテストの書き方
  5. golang でパフォーマンスチューニングする際に気を付けるべきこと

go-github という、Google が開発している GitHub API ライブラリがあるのですが、今回 filosottile さんがたった4行のコードで実行速度を4倍にするという pull-request を書きました。

いったいどういう事かというと、golang の json.Decoder を使って http.Response.Body から JSON を読み取ると最後の改行(EOF)が読み込まれずに残ってしまい、レスポンスを完全に読み切らないまま http.Response.Body.Close() が呼ばれてしまう。これはこれで別に問題のあるコードではないのですが、継続してリクエストを送る場合にレスポンスを完全に読み切っていなかった事でクライアントは物理切断してしまい TLS 接続が再利用されなくなります。この TLS 接続を再利用する為には残りのたった1バイトを読み捨ててあげる必要がある。そこで

defer func() {
    // Drain and close the body to let the Transport reuse the connection
    io.Copy(ioutil.Discard, resp.Body)
    resp.Body.Close()
}()

というコードになったという事です。個人的にはこれは golang 本体がやるべき仕事な気もするのでオススメはしませんし、今後 golang に何かしらの対応が入るのかもしれませんが、今すぐ高速な HTTP 通信が必要という方は試してみるのも良いかもしれません。

ちなみにこの件、Content-Length 分読み取って json.Unmarshal していれば発生しないはずですが json.Decoder のメモリを極力使わないというメリットが使えなくなるというのもあり一長一短ですね。

Go言語によるWebアプリケーション開発 Go言語によるWebアプリケーション開発
Mat Ryer
オライリージャパン / ¥ 3,456 (2016-01-22)
 
発送可能時間:在庫あり。


blog comments powered by Disqus