aws-sdk-ruby で keepalive でハマった
メモ。
ストレージサーバに RiakCS を使って、Python の boto から RiakCS にファイルを送信する。
Ruby で書かれたサーバー(MessagePack-RPC)があり、それが Python で突っ込んだファイルを取得し処理をする。
Python から Ruby のサーバーに対して MessagePack-RPC で RPC 通信を行い、boto で突っ込んだファイルを取得し、処理した結果を RiakCS に戻す。
Python の boto が RiakCS にファイルを短い感覚で突っ込んで、MessagePack-RPC サーバーに対して通知を送っていると、Ruby の aws-sdk が突っ込んだデータを取得できないという事態が発生した。
class RiakCS def connect(configs, logger = nil, bucket_name = '') @logger = logger || Logger.new(STDERR) @configs = configs AWS::config(configs) @bucket_name = bucket_name @connection = AWS::S3.new @logger.debug('Connected to RiakCS') end def list(target_name) items = [] buckets.objects.with_prefix(target_name).each do |obj| @logger.debug("List #{target_name} direcotry. #{obj.key}") items.push(obj.key) end end private def buckets @connection.buckets[@bucket_name] end end
これで、MessagePack-RPC サーバー起動直後は items に正しく取得するファイルが格納されるが、
短い時間*1に新たにファイルを RiakCS に突っ込んだ場合にその突っ込んだファイルが取得できない。
さんざか悩んで、コネクションを使い回してるんじゃないかと思い、コネクションを再接続してみようと、AWS::S3 のインスタンスを list() 内で毎回作り直したりしたが、結果は一緒。
aws-sdk-ruby にはどうやら disconnect のようなメソッドは無い(HTTP なんだからそりゃそうか)。
ふと keep-alive なのかなと思い、aws-sdk-ruby の HTTP リクエストをダンプしてみたら、
Conn keep-alive というのが出ていた。
これかと思い、ドキュメント を読んでみると、
Module: AWS — AWS SDK for Ruby
- http_idle_timeout (Integer) ― default
- 60 ― The number of seconds a persistent connection is allowed to sit idle before it should no longer be used.
というのを見つけた。
AWS::Config で :http_idle_timeout = 0 とかしてやると、無事に新規に突っ込んだファイルを取得できるようになった。
ストレージサーバの keep-alive をオフにするのはどうなのかと思うが、とりあえずこれで運用してみる。
*1:keep-alive の有効時間内