-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
middleware ordering not controlled when in threadsafe! mode #1
Comments
here's an idea -- it would be nice to copy the value of the If doing this, then perhaps it suggests a better place to inject the middleware: app.config.middleware.insert_before 'ActionDispatch:: RequestId', "HerokuRequestId::Middleware" |
Hey, @jjb, thanks for the ideas. You're right that the current implementation would not get reliable loading order in threadsafe mode. I like the idea about copying the header value. I think inserting before ActionDispatch::RequestId could work, but I'm wondering if there's a way to make sure that it loads first. I also just came across this, which I think we could do to make sure to wrap all middleware : https://github.com/lukeludwig/rack_timer/blob/master/lib/rack_timer/stack.rb#L59 |
@jagthedrummer glad you liked the header feature. back to the middleware discussion: what was the rationale for putting it after |
Hey, @jjb. Honestly, I don't remember why it went after |
gotcha so, one option is to set it at position 0. it's possible that another one thing to consider is that if a user IS using rack lock, then it's (i don't know how to check if a middleware is present) |
What would be the downside to having it outside of |
i was thinking along the lines of what you wanted to measure -- "everything |
(so, if you think measuring everything from position 0 is better, i agree) On Fri, May 31, 2013 at 1:32 PM, John Joseph Bachir [email protected] wrote:
|
I think this should do the trick : 628b99e |
Running a quick test in a dummy app to be sure. |
Looks like that does it. heroku-request-id-test$ rake middleware
use HerokuRequestId::Middleware
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffbc919e200>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use ActionDispatch::Head
use Rack::ConditionalGet
use Rack::ETag
use ActionDispatch::BestStandardsSupport
run HerokuRequestIdTest::Application.routes |
some more meandering thoughts: hardcoding it to 0 rubs me the wrong way and seems like it should only be appropriate for very specific reasons. Which also makes me think maybe timing the request, tracking the id, and writing a log are three different concerns. here's what the relevant part of one of my app's middleware stack looks like:
hmmm, what's rack::Runtime do?: https://github.com/rack/rack/blob/master/lib/rack/runtime.rb looks like it times everything below it -- so perhaps:
drawback: requests for static resources won't be handled. Thoughts? getting back to my "maybe timing the request, tracking the id, and writing a log are three different concerns" -- maybe your functionality could be split into two middlewares. one which is concerned with all things regarding heroku request ids, and another which is concerned with all things regarding heroku logs (logs the request id, the request time, and maybe more things in the future). |
I should have mentioned: a reason to not use a hardcoded number is that you will be battling for 0th place with other gems, such as the very popular rack-timeout: https://github.com/kch/rack-timeout/blob/master/lib/rack-timeout.rb |
Hmm... those are some good thoughts. Lemme stew on it for a little while. FYI, I just built and pushed v0.0.7 with the hardcoded 0 spot. v0.0.8 may not be far behind.... |
more exciting developments: i just tried 0.0.7 locally, with rack::lock enabled (threadsafe! not on), using puma, and when hitting the app with concurrent requests i got a lot of errors like this:
I commented out everything in the middleware to see if any of its features in particular are the culprit. i got it down to this and the problem did not go away: def call(env)
@status, @headers, @response = @app.call(env)
[@status, @headers, self]
end
def each(&block)
@response.each(&block)
end Puma is multithreaded, so when using puma AND rack::lock, then everything before rack::lock is multithreaded. however, i don't see any non-threadsafe code. I'm suspicious of the use of another thought: when appending to the body, this has to be done BEFORE the deflate middleware, otherwise it will be appended to a zipped blob instead of to text. So, this is a reason why it absolutely cannot be set at position 0. |
see discussion in Octo-Labs#1
Wow. OK, clearly the loading scheme in 0.0.7 is not good. I think your idea of inserting before I'm very surprised that the stripped down version was causing threading issues. I can see how the Good point about the deflate middleware. |
OK, first step. Loading in a (hopefully) better place. 705bf74 |
I just pushed a change that removes all of the timing code from this gem and relies on the header set by |
if an app is in threadsafe! mode, then the middleware ordering won't be controlled (or maybe the middleware won't be inserted at all? not sure)
https://github.com/Octo-Labs/heroku-request-id/blob/master/lib/heroku-request-id/railtie.rb
given that threadsafe! will be on by default in rails 4, and in general is now recommended even for single-threaded apps, this should probably be accounted for.
The text was updated successfully, but these errors were encountered: