2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/spec/integrity/middleware_order_spec.rb
Alan Guo Xiang Tan 9c781af9d1
PERF: Reject anonymous requests with 503 upon aggressive queuing (#36519)
This commit adds a default protection to all Discourse app which will
turn away all anonymous requests that has queued for more than the
duration configured
by the `reject_anonymous_min_queue_seconds` global setting, 1 second
by default. A queue time of 1 second is a sign that the app is very
overloaded so we are opting to turn away anonymous requests when that
happens.

While there may be better solutions like introducing an adaptive
concurrency limit somewhere in the stack, we like this solution for its
simplicity. We may consider the more complex solutions in the future but
the time is not now.

Other significant changes in this commit:

1. Moved setting of the `REQUEST_QUEUE_SECONDS` key in `env` to
   `Middleware::ProcessingRequest`.
2. Introduction of the `reject_anonymous_min_queue_seconds` global
   Setting.
2025-12-18 10:23:42 +08:00

58 lines
2 KiB
Ruby

# frozen_string_literal: true
RSpec.describe "Middleware order" do
let(:expected_middlewares) do
[
BlockRequestsMiddleware,
TestMultisiteMiddleware,
Middleware::ProcessingRequest,
Middleware::OverloadProtections,
ActionDispatch::RemoteIp,
Middleware::RequestTracker,
MessageBus::Rack::Middleware,
Rack::Sendfile,
ActionDispatch::Static,
Propshaft::Server,
ActionDispatch::Executor,
Rack::MethodOverride,
Middleware::EnforceHostname,
ActionDispatch::RequestId,
SilenceLogger,
Middleware::DefaultHeaders,
ActionDispatch::ShowExceptions,
ActionDispatch::DebugExceptions,
ActionDispatch::Callbacks,
ActionDispatch::Cookies,
ActionDispatch::Session::DiscourseCookieStore,
Discourse::Cors,
ActionDispatch::Flash,
RspecErrorTracker,
Middleware::CspScriptNonceInjector,
Middleware::AnonymousCache,
ContentSecurityPolicy::Middleware,
ActionDispatch::PermissionsPolicy::Middleware,
Rack::Head,
Rack::ConditionalGet,
Rack::TempfileReaper,
Middleware::CrawlerHooks,
Middleware::OmniauthBypassMiddleware,
]
end
let(:actual_middlewares) { Rails.configuration.middleware.middlewares }
let(:remote_ip_index) { actual_middlewares.index(ActionDispatch::RemoteIp) }
let(:request_tracker_index) { actual_middlewares.index(Middleware::RequestTracker) }
it "has the correct order of middlewares" do
expect(actual_middlewares).to eq(expected_middlewares)
end
it "ensures that ActionDispatch::RemoteIp comes before Middleware::RequestTracker" do
expect(remote_ip_index).to be < request_tracker_index
end
it "ensures that Middleware::DefaultHeaders comes before ActionDispatch::ShowExceptions" do
default_headers_index = actual_middlewares.index(Middleware::DefaultHeaders)
show_exceptions_index = actual_middlewares.index(ActionDispatch::ShowExceptions)
expect(default_headers_index).to be < show_exceptions_index
end
end