3

My Rails 3.1 app uses an engine and I want to know if access to this engine is threadsafe.

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 like this:

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

In my main app, I have the threadsafe! configuration option set. I know that with threadsafe! enabled, each Controller lives in it's own thread for each request.

However, is this Module threadsafe? I suspect that there is only one copy of this module for all requests, so it is not inherently thread safe, and requires manual synchronization using something like a Mutex. Specifically, I have code that sets the header for the HTTP request outside of the ActiveResource class WebResource. Could this cause a threading issue?

Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
Oleksi
  • 12,947
  • 4
  • 56
  • 80

1 Answers1

3

It will depend on what you do inside this method as to whether it is thread safe. If it touches no class variables, then it is thread safe.

If it stores or sets information at the class level and assumes that no other method is going to touch that information before it uses it again, then it is not thread safe.

Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
  • Thanks @Jesse. I've updated my question to provide more details. While I don't touch any class variables/global state, I am still not sure if this will work. I am setting the HTTP header information outside of the engine, in my controller. Do you know if each Rails request will get it's own instance of the Engine/WebResource.headers? – Oleksi Sep 18 '12 at 22:13
  • How is `MyModule::WebResource.headers` implemented inside Ruby/Rails? Is it at the class level? – Oleksi Sep 19 '12 at 01:02
  • What is WebResource ? isn't that an activerecord class you've defined? – Jesse Wolgamott Sep 19 '12 at 01:41
  • It's a subclass of ActiveResource, not ActiveRecord. I was wondering if I set `MyModule::WebResource.headers` in my controller, does it only get changed in that controller, or for all controllers/requests? That is, does each controller have an instance of WebResource, or is there only one for the engine, and all the controllers use the same reference. – Oleksi Sep 19 '12 at 02:24
  • Ahh, activeresource! I recommend editing your question to specify asking about ActiveResource. no, that is not thread-safe ... here is a way to use it: http://stackoverflow.com/questions/8088126/is-it-thread-safe-to-set-active-resource-http-authentication-on-a-per-user-basis – Jesse Wolgamott Sep 19 '12 at 13:50
  • Thanks for your help. I implemented a similar work around to solve this issue. – Oleksi Sep 19 '12 at 21:12
  • Update: ActiveResource now stores headers, site, proxy, basic auth and the connection itself in thread-local variables to make it all thread-safe: https://github.com/rails/activeresource/commit/538588ddba9ffc9bf356790e9186dc7e6adad12f – mltsy Nov 28 '17 at 18:43