Search code examples
ruby-on-railsruby-on-rails-3thread-safetyactiveresource

Setting Rails ActiveResource headers in a thread safe way


I am making calls to an ActiveResource object inside an engine, and I need to set the headers in a thread safe way.

I have /lib/mymodule.rb in the engine and it looks something like this:

module MyModule
  def self.my_method()
    begin
       data = WebResource.find(:all) # Where WebResource < ActiveResource::Base
    rescue
       data = nil
    end

    return data
  end
end

Then in my views/controllers, I call this method roughly like this:

WebResource.headers[:some_id] = cookies[:some_id]
MyModule::my_method()

After asking this question and doing some reading, it looks like this is not threadsafe because I set headers at the class-level.

What is the best way to set these headers in a thread safe way?


Solution

  • Solved the issue. The solution is influenced by this question. Essentially, I overwrite the self.headers() method to store headers in Thread.current, instead of a class variable.

    It looks like this:

    class WebResource < ActiveResource::Base
    
      # ...
    
      class << self
    
        def headers
          Thread.current["active.resource.currentthread.headers"] = {} if Thread.current["active.resource.currentthread.headers"].blank?
          Thread.current["active.resource.currentthread.headers"]
        end
    
      end
    end