3

最初の起動時に、サーバー バックエンドで 2 つの異なる API エンドポイントを呼び出すこのアプリがあります (両方とも目的が大きく異なります)。ただし、どちらの 2 つの方法にも、ヘッダーで渡された情報 (デバイス識別子 + API キー)before_filterを使用して呼び出しを認証する があります。HTTP_AUTH

指定された識別子を持つデバイス テーブルから行が見つからない場合、その識別子を持つ新しい行が自動的に作成されます。私の問題は、2 つの呼び出しが非常に同時であるため、両方の要求がレコードを見つけられず、両方が新しいデバイス行を作成することがあるようです (その結果、同じデバイス識別子を持つ行が重複します)。

私の認証方法は次のようになります。

def current_user      
    authenticate_with_http_basic do |udid, secret|
        if secret == APP_SECRET
            @device = Device.find_by_udid(udid)

            if !@device
                @device = Device.new
                @device.udid = udid
                @device.created_on = DateTime.now.utc
            end

            // set a bunch of properties on @device
            @device.connected_at = DateTime.now.utc
            @device.save
        end
    end
end 
4

1 に答える 1

8

これが、一意のインデックスが発明された理由です。一意のインデックスを設定するとudid(udidごとに1つのデバイスのみが存在できるように)、コードは次のようになります(擬似コード)。

def process
  device = Device.find

  unless device
    device = Device.create
  end

  # do your work with the device

rescue ActiveRecord::RecordNotUnique
  retry # this is an actual ruby keyword. It means "run this begin..end block 
        # again". In this case, there's an implicit begin..end block, which is 
        # the method body.
end

2番目のワーカーがすでに存在するudidを使用してデバイスを挿入しようとすると、エラーが発生するため、検索を再試行する必要があります。

于 2012-09-18T04:53:52.953 に答える