-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
In version 2.2.x, Rack::Lint does this check in _call:
assert("response #{ary.inspect} is not an Array , but #{ary.class}") {
ary.kind_of? Array
}
assert("response array #{ary.inspect} has #{ary.size} elements instead of 3") {
ary.size == 3
}Even if the assertion is successful, the result of @app.call(env) is inspected, allocated, and dropped into a string that will never be used. Twice. For every middleware being linted. @app.call(env) returns an array of status (no big deal), headers (this is rather large once you've got stuff like Devise loaded), and body (hundreds to thousands of kilobytes!). So, Rack is allocating RAM for the response body at least three times, but probably dozens of times.
This resulted in this performance regression of our large production application (purple is "Middleware"):
I ran a transaction trace and found that each of the ~15 middlewares eats up about 1.2% of the entire request time in #inspect, for a total of 16%.
We've downgraded to 2.1.2 for the time being. I'm not sure if you actually need to inspect the array, but if you do, I'd suggest only doing it in development.
