Skip to content

Instantly share code, notes, and snippets.

@ElMassimo
Last active April 19, 2017 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ElMassimo/e2f99848db6a415f1aaa to your computer and use it in GitHub Desktop.
Save ElMassimo/e2f99848db6a415f1aaa to your computer and use it in GitHub Desktop.
Thread with access to a shared Request Context
# Public: Module that overrides Thread initialization to preserve the request context.
module ThreadWithContext
# Public: Returns a new Thread that preserves the context of the current request.
def new(*args)
request_id = Thread.current[:request_id]
super(*args) {
Thread.current[:request_id] = request_id
yield *args
}
end
end
# Use at your own peril, when you modify stdlib classes many things can go wrong :)
Thread.class_eval do
class << self
prepend ThreadWithContext
end
end
@ElMassimo
Copy link
Author

Prepend and forget? 😄

@gtmax
Copy link

gtmax commented Apr 19, 2017

Awesome, thanks a lot man 👍 Just a note about Fibers - Thread.current[] storage is Fiber-local, see e.g. http://www.virtuouscode.com/2012/02/02/ruby-thread-locals-are-also-fiber-local/ . Since the current implementation of request_store_rails relies on Thread.current[], the request_id needs to be propagated to new Fibers as well as new Threads in this "prepend and forget" gist.

Alternatively, Thread.current[] can be changed to Thread-scoped Thread#thread_variable_set/get, both in this gist and the gem impl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment