web-dev-qa-db-ja.com

Ruby error Net :: ReadTimeout

Httpartyを使用して一連のAPI呼び出しを行っています。最初の2つのAPI呼び出しは成功しますが、3番目のAPI呼び出しは失敗します。約60秒間(デフォルトのタイムアウト期間)一時停止し、次のエラーを返します。

/Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/protocol.rb:158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/protocol.rb:152:in `rbuf_fill'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/protocol.rb:134:in `readuntil'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/protocol.rb:144:in `readline'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http/response.rb:39:in `read_status_line'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http/response.rb:28:in `read_new'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:1406:in `block in transport_request'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:1403:in `catch'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:1403:in `transport_request'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:1376:in `request'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:1369:in `block in request'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:852:in `start'
    from /Users/luigi/.rvm/rubies/Ruby-2.0.0-p247/lib/Ruby/2.0.0/net/http.rb:1367:in `request'
    from /Users/luigi/.rvm/gems/Ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty/request.rb:93:in `perform'
    from /Users/luigi/.rvm/gems/Ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty.rb:486:in `perform_request'
    from /Users/luigi/.rvm/gems/Ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty.rb:423:in `get'
    from /Users/jmccann/.rvm/gems/Ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty.rb:518:in `get'

私の質問は、なぜこれが起こっているのですか?このエラーはAPIのエラーを示していますか、それを引き起こすためにできることはありますか?

私のコード:

これは機能するコールです:

url = HTTParty.get("https://dev.test.com#{call}",
    :basic_auth => auth,
    :headers => {'Accept' => 'application/json' } )

これは機能しない呼び出しです:

url = HTTParty.get("https://dev.test.com#{call}",
    :basic_auth => auth,
    :headers => {'Accept' => 'application/json' } )

変更されるのは実際のcallだけですが、APIドキュメントによると両方とも有効な呼び出しです。

21
Luigi

Ruby docs: http://Ruby-doc.org/stdlib-2.1.2/libdoc/net/http/rdoc/Net/HTTP.html から

1つのブロックが読み取られるまで待機する秒数(1つのread(2)呼び出しを介して)。秒の小数部の浮動小数点数を含む、任意の数値を使用できます。 HTTPオブジェクトがこの数秒でデータを読み取れない場合、Net :: ReadTimeout例外が発生します。デフォルト値は60秒です。

callとは何ですか?サービスエンドポイントは異なりますか?レコードをページングしていますか? APIは、多くの場合、DDOS攻撃を防ぐために発信者を制限します。再試行ロジックでAPI呼び出しをラップするか、スリープコードを追加してみてください。

15
jaysqrd