nukeproof/oanda_api のコネクションリーク問題とその対策
OANDA fx Trade APIのRubyクライアント「nukeproof/oanda_api」には、TCPコネクションリークの問題があり、長時間連続で利用しているとファイルディスクリプタが枯渇します。
内部で利用している persistent_http の古いバージョンにある不具合が原因(最新の2.0.1では改修済み)のため、Gemfileなどで最新バージョンを使うようにすると回避できます。
gem 'persistent_http', '2.0.1'
問題の詳細
Jijiを10日程度連続稼働させていて発覚。突然、以下のエラーが発生するようになりました。
E, [2015-12-09T01:23:06.337582 #7932] ERROR -- : Too many open files - getaddrinfo (Errno::EMFILE) /home/yamautim/.rbenv/versions/2.2.3/lib/ruby/2.2.0/net/http.rb:879:in `initialize' /home/yamautim/.rbenv/versions/2.2.3/lib/ruby/2.2.0/net/http.rb:879:in `open' /home/yamautim/.rbenv/versions/2.2.3/lib/ruby/2.2.0/net/http.rb:879:in `block in connect'
lsof コマンドの出力行数も少しずつ増えていきます。
$ lsof -p <Jijiのpid> | wc -l 77 $ lsof -p <Jijiのpid> | wc -l 79
起動直後と、しばらく起動した後で、lsofの出力結果のDiffをとると、CLOSE_WAITのhttpsコネクションが増加していました。
ruby 4389 xxxx 23u IPv4 9265756 0t0 TCP localhost.localdomain:35773->unknown.xxxx.net:https (CLOSE_WAIT)
外向きのHTTPS通信なので、OANDA へのアクセスっぽい。
原因
最初にも書きましたが、persistent_http の古いバージョンにある不具合が原因です。最新の 2.0.1 を使えば改修されます。
- 1.0.6では、内部で利用しているGenePoolに渡すオプションがnilになっており、コネクションの破棄が正しく行われない状態になっています。
- このコミットで改修されていて、最新の 2.0.1 を使えばOK。
- ただし、oanda_api が直接依存している persistent_httparty で バージョン2以下を使うよう明示されているため、普通に使うと 1.0.6 が使われてしまいます。
- このため、Gemfileなどで最新バージョンを使うように明示する等の対応が必要です。
- ちなみに、persistent_httparty に、依存するpersistent_httpのバージョンを上げるPull Requestはあるのですが、マージされていないようです・・・。