Mi API permite a los usuarios comprar ciertos artículos únicos, donde cada artículo solo se puede vender a un usuario. Entonces, cuando varios usuarios intentan comprar el mismo artículo, un usuario debe obtener la respuesta: ok y el otro usuario debe obtener la respuesta too_late.¿Solicitudes de carpincho concurrentes de subprocesos múltiples?
Ahora, parece haber errores en mi código. Una condición de carrera. Si dos usuarios intentan comprar el mismo artículo al mismo tiempo, ambos obtienen la respuesta ok. El problema es claramente reproducible en producción. Ahora he escrito una prueba sencilla que intenta reproducirla a través de 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
Parece que no ejecuta las consultas al mismo tiempo. Para probar esto, puse el código siguiente en mi acción del controlador:
puts "Is it concurrent?"
sleep 0.2
puts "Oh Noez."
espera que la producción sería, si las solicitudes son concurrentes:
Is it concurrent?
Is it concurrent?
Oh Noez.
Oh Noez.
Sin embargo, me sale el siguiente resultado:
Is it concurrent?
Oh Noez.
Is it concurrent?
Oh Noez.
Lo que me dice que las solicitudes de capibara no se ejecutan al mismo tiempo, sino de a una por vez. ¿Cómo hago que mis solicitudes de capabara sean simultáneas?
El ejemplo de código anterior no se parece al actual DSL de Capybara. Se parece más a una prueba de controlador simple usando Rack :: Test. ¿Eso es lo que es? –