My API を使用すると、ユーザーは特定のユニークなアイテムを購入できます。各アイテムは 1 人のユーザーにのみ販売できます。そのため、複数のユーザーが同じアイテムを購入しようとすると、1 人のユーザーが応答: okを受け取り、もう 1 人のユーザーが応答too_lateを受け取る必要があります。
今、私のコードにバグがあるようです。競合状態。2 人のユーザーが同じアイテムを同時に購入しようとすると、どちらもokという回答が得られます。この問題は、本番環境で明らかに再現可能です。これで、rspec を介してそれを再現しようとする簡単なテストを作成しました。
context "when I try to provoke a race condition" do
# ...
before do
@concurrent_requests = 2.times.map do
Thread.new do
Thread.current[:answer] = post "/api/v1/item/buy.json", :id => item.id
end
end
@answers = @concurrent_requests.map do |th|
th.join
th[:answer].body
end
end
it "should only sell the item to one user" do
@answers.sort.should == ["ok", "too_late"].sort
end
end
同時にクエリを実行していないようです。これをテストするために、コントローラー アクションに次のコードを追加します。
puts "Is it concurrent?"
sleep 0.2
puts "Oh Noez."
リクエストが並行している場合、予想される出力は次のようになります。
Is it concurrent?
Is it concurrent?
Oh Noez.
Oh Noez.
ただし、次の出力が得られます。
Is it concurrent?
Oh Noez.
Is it concurrent?
Oh Noez.
これは、カピバラのリクエストが同時に実行されるのではなく、一度に 1 つずつ実行されることを示しています。カパバラ リクエストを同時に行うにはどうすればよいですか?