【问题标题】:Ruby's `File.exist?` ThreadErrorRuby 的 `File.exist?` ThreadError
【发布时间】:2012-11-26 13:49:51
【问题描述】:

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

这是背景。我正在改进一些旧的 web 应用程序,它托管大约 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) ruby​​gems。

感谢您的帮助。

【问题讨论】:

  • 我发现这张灯塔票似乎在谈论您遇到的问题:rails.lighthouseapp.com/projects/8994/tickets/4565 这似乎与在开发中将config.cache_classes 设置为false 有关。但是,对于 Rails 2.3.6,该问题已标记为已解决,因此它可能不适用于您。希望这能有所帮助。
  • @Raf 它适用!谢谢!现在,为了方便起见,我需要一种方法来使用将 cache_classes 设置为 false 的中间件,但您的发现将有很大帮助。

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


【解决方案1】:

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

错误:

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

好:

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

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 1970-01-01
    • 2015-01-25
    • 2019-02-18
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多