読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

nukeproof/oanda_api のコネクションリーク問題とその対策

OANDA fx Trade APIRubyクライアント「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はあるのですが、マージされていないようです・・・。