Ruby的`File.exist?`ThreadError

时间:2012-11-26 13:49:51

标签: ruby-on-rails rack ruby-on-rails-2 ruby-1.8.7

我在中间件中使用Ruby的File.exist?方法时遇到错误。我不明白为什么。

这是背景。我正在改进一些旧的webapp,它可以容纳大约100GB的照片并且不断增长。我需要在我的计算机上复制生产环境,但我不想下载所有这些文件。如果应用程序可以检查我的文件系统中是否存在给定文件并将其提供或重定向到生产服务器,那将会很棒。

我以为我可以将简单的机架应用作为中间件:

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

然而,抛出以下错误(并非总是如此,对于某些图片它只是起作用):

[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

我对此问题感到惊讶,因为它是在Rack::Lock提供的互斥锁内部运行的。在Rack::Lock之前移动此中间件无济于事。删除File.exist?后,错误消失了。这是Ruby 1.8.7,在Rails 2.3.9上有最新的(1.8.24)rubygems。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

实际上,问题有点不同。响应数组的最后一个元素也应该是一个数组。

错误:

[307, { "Location" => "http://production.example.com" + env["PATH_INFO"] }, ""]

好:

[307, { "Location" => "http://production.example.com" + env["PATH_INFO"] }, []]