aws-sdk-ruby で keepalive でハマった

メモ。
ストレージサーバに RiakCS を使って、Python の boto から RiakCS にファイルを送信する。
Ruby で書かれたサーバー(MessagePack-RPC)があり、それが Python で突っ込んだファイルを取得し処理をする。
Python から Ruby のサーバーに対して MessagePack-RPC で RPC 通信を行い、boto で突っ込んだファイルを取得し、処理した結果を RiakCS に戻す。

Python の boto が RiakCS にファイルを短い感覚で突っ込んで、MessagePack-RPC サーバーに対して通知を送っていると、Rubyaws-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 というのが出ていた。
これかと思い、ドキュメント を読んでみると、

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.
Module: AWS — AWS SDK for Ruby

というのを見つけた。
AWS::Config で :http_idle_timeout = 0 とかしてやると、無事に新規に突っ込んだファイルを取得できるようになった。


ストレージサーバの keep-alive をオフにするのはどうなのかと思うが、とりあえずこれで運用してみる。

*1:keep-alive の有効時間内