Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safety of Thread.current[] usage in rails

I keep getting conflicting opinions on the practice of storing information in the Thread.current hash (e.g., the current_user, the current subdomain, etc.). The technique has been proposed as a way to simplify later processing within the model layer (query scoping, auditing, etc.).

  • Why are my thread variables intermittent in Rails?
  • Alternative to using Thread.current in API wrapper for Rails
  • Are Thread.current[] values and class level attributes safe to use in rails?

Many consider the practice unacceptable because it breaks the MVC pattern. Others express concerns about reliability/safety of the approach, and my 2-part question focuses on the latter aspect.

  1. Is the Thread.current hash guaranteed to be available and private to one and only one response, throughout its entire cycle?

  2. I understand that a thread, at the end of a response, may well be handed over to other incoming requests, thereby leaking any information stored in Thread.current. Would clearing such information before the end of the response (e.g. by executing Thread.current[:user] = nil from a controller's after_filter) suffice in preventing such security breach?

Thanks! Giuseppe

like image 739
Giuseppe Avatar asked Oct 25 '11 21:10

Giuseppe


People also ask

What is thread safe rails?

Thread safety in Rails avoids the aforementioned race conditions. It means that, in a multithreaded web-server environment, our code should be thread safe. If multiple threads are accessing our web application then our shared data should not be corrupted when all threads finish processing.

What is Ruby thread safe?

Thread-safe globalsRuby offers built-it support for so-called thread-local variables. Each thread can work as a kind of a hash for storing values accessible globally in the app but only from this single thread.

Does Rails use threads?

Rails as a framework is thread-safe. So, the answer is yes!

What is thread current?

The current thread is the currently executing thread object in Java. The method currentThread() of the Thread class can be used to obtain the current thread. This method requires no parameters.


1 Answers

There is not an specific reason to stay away from thread-local variables, the main issues are:

  • it's harder to test them, as you will have to remember to set the thread-local variables when you're testing out code that uses it
  • classes that use thread locals will need knowledge that these objects are not available to them but inside a thread-local variable and this kind of indirection usually breaks the law of demeter
  • not cleaning up thread-locals might be an issue if your framework reuses threads (the thread-local variable would be already initiated and code that relies on ||= calls to initialize variables might fail

So, while it's not completely out of question to use, the best approach is not to use them, but from time to time you hit a wall where a thread local is going to be the simplest possible solution without changing quite a lot of code and you will have to compromise, have a less than perfect object oriented model with the thread local or changing quite a lot of code to do the same.

So, it's mostly a matter of thinking which is going to be the best solution for your case and if you're really going down the thread-local path, I'd surely advise you to do it with blocks that remember to clean up after they are done, like the following:

around_filter :do_with_current_user  def do_with_current_user     Thread.current[:current_user] = self.current_user     begin         yield     ensure         Thread.current[:current_user] = nil     end       end 

This ensures the thread local variable is cleaned up before being used if this thread is recycled.

like image 196
Maurício Linhares Avatar answered Sep 22 '22 12:09

Maurício Linhares