Мой API позволяет пользователям покупать определенные уникальные предметы, где каждый предмет может быть продан только одному пользователю. Поэтому, когда несколько пользователей пытаются купить один и тот же товар, один пользователь должен получить ответ: ok, а другой пользователь должен получить ответ too_late.
Кажется, в моем коде есть ошибка. Состояние гонки. Если два пользователя попытаются купить один и тот же товар одновременно, они оба получат ответ 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.
Что говорит мне, что запросы капибары запускать не одновременно, а по одному. Как сделать запросы капабара одновременными?