I am encountering errors when I am using Ruby's File.exist?
method in middleware. I have no idea why.
This is the background. I am improving some old webapp which hosts around 100GB of photos and growing. I need to replicate production environment on my computer, but I don't want to download all those files. It would be great if app could check if given file exists in my filesystem and either serve it or redirect to production server.
I thought I could do simple rack app as middleware:
require 'rack/utils'
class FetchMissingPicturesMiddleware
def initialize(app)
@app = app
end
def call(env)
if env["PATH_INFO"].starts_with? "/system/attachments/" && !File.exist?(Rails.root.join('public').join(env["PATH_INFO"][1..-1]))
[307, { "Location" => "http://production.example.com" + env["PATH_INFO"] }, ""]
else
@app.call(env)
end
end
end
However, following error is thrown (not always, for some pictures it just works):
[2012-11-26 14:28:12] ERROR ThreadError: thread 0x10aed55e8 tried to join itself
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/actionpack-2.3.9/lib/action_controller/reloader.rb:31:in `lock'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/actionpack-2.3.9/lib/action_controller/reloader.rb:31:in `run'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/actionpack-2.3.9/lib/action_controller/dispatcher.rb:108:in `call'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rails-2.3.9/lib/rails/rack/static.rb:31:in `call'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rack-1.1.3/lib/rack/urlmap.rb:47:in `call'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in `each'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in `call'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rails-2.3.9/lib/rails/rack/log_tailer.rb:17:in `call'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rack-1.1.3/lib/rack/content_length.rb:13:in `call'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rack-1.1.3/lib/rack/handler/webrick.rb:48:in `service'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:162:in `start'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:95:in `start'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:92:in `each'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:92:in `start'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:23:in `start'
/Users/skale/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/webrick/server.rb:82:in `start'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rack-1.1.3/lib/rack/handler/webrick.rb:14:in `run'
/Users/skale/.rvm/gems/ruby-1.8.7-p371/gems/rails-2.3.9/lib/commands/server.rb:111
script/server:6:in `require'
script/server:6
I am surprised with this issue because it's run inside mutex provided by Rack::Lock
. Moving this middleware before Rack::Lock
does not help. After removing File.exist?
errors are gone. This is Ruby 1.8.7 with freshest (1.8.24) rubygems on Rails 2.3.9.
Thanks for your help.