我的API允许用户购买某些独特的物品,其中每个物品只能出售给一个用户。因此,当多个用户试图购买相同的物品时,一个用户应该得到回应: ok另一个用户应该得到回应 too_late。多线程并发水豚请求?
现在,我的代码中似乎有bug。竞赛条件。如果两个用户同时尝试购买相同的物品,他们都会得到答案 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.
这告诉我,水豚请求不是同时运行,而是一次运行一次。 如何使我的capabara请求并发?
上面的代码示例看起来不像当前的Capybara DSL。它看起来更像是一个使用Rack :: Test的简单控制器测试。那是什么? –