Description
I tried running my Rails app using JRuby in threadsafe mode but saw what appeared to be a race condition. Basically if two requests came in around the same time, both resulting in dragonfly jobs for resizing different images, one image would be resized to the size that the other image was supposed to be resized to. For example, if a requests came in to resize image A to X by Y and image B to U by V, then sometimes image A would be resized to U by V!
The problem probably stems from a Dragonfly app not being itself threadsafe. If two threads request Dragonfly[:images], they will get back the same app and will try to run jobs on it simultaneously.
I started to look at the Dragonfly code and quickly came across an instance of non-threadsafe code on Dragonfly::App at https://github.com/markevans/dragonfly/blob/master/lib/dragonfly/app.rb#L21
def apps
@apps ||= {}
end
And there's similar instances of the non threadsafe pattern @var ||= foo
in other parts of the code. That pattern is probably not what's causing the race condition I'm seeing. That's just the start of a threadsafety audit.
Being able to run in threadsafe mode in jruby setup results in substantially decreased memory usage. It would be great to be able to use dragonfly in such a setup. Furthermore, with Rails 4.0 turning on threadsafe mode by default, threadsafety is becoming increasingly important in general in the Rails community.