-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
I was debugging CSRF exceptions in our test suite when running on a resource starved machine with just 1 puma thread.
It turned out a combination of fetch calls in setTimeout and puma not processing requests fast enough lead to requests leaking in between tests and producing CSRF exceptions.
Not sure exactly why or how it slips through the middleware - maybe there is a successful check before puma accepts more requests from the backlog.
In my testing this pretty basic monkeypatch fixes the issue and drains all the requests in between tests.
module CapybaraWaitForPumaBacklog
extend ActiveSupport::Concern
prepended do
class_attribute :wait_for_pending_puma_backlog, default: true
end
def pending_requests?
super || puma_backlog_pending?
end
def puma_backlog_pending?
wait_for_pending_puma_backlog && puma_backlog > 0
end
private
def find_puma_server
@_puma_server ||= ObjectSpace.each_object(::Puma::Server).find(&:running)
end
def puma_backlog
server = find_puma_server
server ? server.backlog : 0
end
end
Capybara::Server::Middleware.prepend(CapybaraWaitForPumaBacklog)I'd like to contribute to capybara not exactly this, but rather a Puma plugin that would produce the same result and extend Capybara::Server#pending_requests? to check the server plugin in addition to the middleware. I don't have the exact design worked out yet.
Is that something worth contributing? I think it could remove some flakiness for people.