Net::HTTP、ZlibとFiberError

咳といいます。

Net::HTTP#requestをブロック付きで呼び出し、ブロックの中で
Net::HTTPResponse#read_bodyをブロック付きで呼び出しています。

例えばこんな雰囲気。

oauth.request(:GET, 'https://userstream.twitter.com/2/user.json') do 

|r|
r.read_body do |chunk|
json.push(chunk) # ←ここ
end
end

内側のブロックの中でFiberを切り替えると次のようなFiberError例外が発生します。

Exception FiberError' at drip_tw.rb:36 - fiber called across stack rewinding barrier Exception Zlib::BufError’ at
/usr/local/lib/ruby/2.2.0/net/http/response.rb:357 - buffer error
Exception `Zlib::BufError’ at /usr/local/lib/ruby/2.2.0/net/http.rb:1442

  • buffer error
    /usr/local/lib/ruby/2.2.0/net/http/response.rb:357:in finish': buffer error (Zlib::BufError) from /usr/local/lib/ruby/2.2.0/net/http/response.rb:357:in finish’
    from /usr/local/lib/ruby/2.2.0/net/http/response.rb:262:in ensure in inflater' from /usr/local/lib/ruby/2.2.0/net/http/response.rb:262:in inflater’
    from /usr/local/lib/ruby/2.2.0/net/http/response.rb:274:in
    read_body_0' from /usr/local/lib/ruby/2.2.0/net/http/response.rb:201:in read_body’
    from drip_tw.rb:180:in block in drip_stream' from /usr/local/lib/ruby/2.2.0/net/http.rb:1415:in block (2 levels)
    in transport_request’
    from /usr/local/lib/ruby/2.2.0/net/http/response.rb:162:in
    reading_body' from /usr/local/lib/ruby/2.2.0/net/http.rb:1414:in block in
    transport_request’
    from /usr/local/lib/ruby/2.2.0/net/http.rb:1405:in catch' from /usr/local/lib/ruby/2.2.0/net/http.rb:1405:in transport_request’
    from /usr/local/lib/ruby/2.2.0/net/http.rb:1378:in request' from /usr/local/lib/ruby/2.2.0/net/http.rb:1371:in block in request’
    from /usr/local/lib/ruby/2.2.0/net/http.rb:853:in start' from /usr/local/lib/ruby/2.2.0/net/http.rb:1369:in request’
    from drip_tw.rb:118:in request' from drip_tw.rb:179:in drip_stream’
    from drip_tw.rb:298:in `’

Rubyのバージョンはruby 2.2.0dev (2014-02-10 trunk 44902) [x86_64-darwin13.0]。
1.9系の頃は動いていたスクリプトです。
Fiberと同様な動作をするThread版を使うと例外は発生しません。

Zlibがrb_protect()しているときにFiberを切り替えているってことでしょうか?(勘)

再現させる最小のコードになってないし実行の準備がめんどくさいけど、件のコードはこちらです。

(178行目のDripFiberをDripThreadにするとThread版になります)