Amazon SimpleDBのConsistentReadを指定してみる
SimpleRecordというSimpleDB専用のActiveRecordクローンを試しているときに登録したはずのデータが取得できない現象が頻発しました。
POSTでデータ登録 -> Redirect GETで登録したデータを取得して表示しようとしたら、データが取得できてない!という流れです。
これはEventually Consistentが働いている現象なんだなーと思いました。(取得するデータが最新の状態である保証がない)
SimpleDBは今年の2月に取得するデータが最新の状態であることを保証するオプション「ConsistentRead」が追加されていました。
が、SimpleRecordもその中で使われているawsもConsistentReadは未対応のようです。
なので無理矢理ConsistentReadを使うように変えてみました。
aws-2.3.9/lib/awsbase/right_awsbase.rb
def self.sign_request_v2(aws_secret_access_key, service_hash, http_verb, host, uri) fix_service_params(service_hash, '2') # select a signing method (make an old openssl working with sha1) # make 'HmacSHA256' to be a default one service_hash['SignatureMethod'] = 'HmacSHA256' unless ['HmacSHA256', 'HmacSHA1'].include?(service_hash['SignatureMethod']) service_hash['SignatureMethod'] = 'HmacSHA1' unless @@digest256 #FORCE ConsistentRead service_hash['ConsistentRead'] = 'true' # select a digest digest = (service_hash['SignatureMethod'] == 'HmacSHA256' ? @@digest256 : @@digest1) # form string to sign canonical_string = service_hash.keys.sort.map do |key| "#{amz_escape(key)}=#{amz_escape(service_hash[key])}" end.join('&') string_to_sign = "#{http_verb.to_s.upcase}\n#{host.downcase}\n#{uri}\n#{canonical_string}" # sign the string signature = escape_sig(Base64.encode64(OpenSSL::HMAC.digest(digest, aws_secret_access_key, string_to_sign)).strip) ret = "#{canonical_string}&Signature=#{signature}" # puts 'full=' + ret.inspect ret end
この
service_hash['ConsistentRead'] = 'true'
一行を追加です。
これでConsistentReadできているようです(たぶん)
クエリーごとに指定できるようなのがほんとはええわな。
Eventually Consistentなデータストアを使う開発では気をつけよう。