【问题标题】:Why are all of my files in use by a Rails app?为什么 Rails 应用程序正在使用我的所有文件?
【发布时间】:2018-01-12 11:59:12
【问题描述】:

我们有一个管理图像文件的 Rails (5.0.5) 应用程序。用户通过实验室 PC​​ 将文件放置到联网的“保管箱”中,然后通过应用程序“认领”它们,从而将它们移动到单独的隐藏存储目录中。

我想定期删除此保管箱中的文件,但目录中的所有 240 多个图像都“正在使用”并且无法删除。它们可以在网络共享目录之间移动,但不能删除。

我认为这可能是安装的网络驱动器上的权限问题,但sudo lsof 显示:

ruby    26542 appuser  242r   REG   0,41   757370 32483 /mnt/filestore/dropbox/SCB EXAM.JPG

ps ax | grep 26542 显示:

26542 ?        Sl     0:02 Passenger RubyApp: /var/www/app/current (production)

据我所知,该应用程序仅访问此保管箱目录以提供其内容列表、将单个文件移动到存储中以及从存储中返回文件。我无法在本地重现该问题。

什么可以让这些文件被应用“使用”?我可以修复它以便在不停止服务器的情况下删除文件吗?

如果有帮助,这里是列出图像的代码:

  def self.list_dropbox_images
    # returns array of hashes with keys "name" (only JPGs) and "time" (creation time)
    # File::FNM_CASEFOLD makes it case-insensitive. Nice.
    dropbox_dir.children.map { |child|
      if child.fnmatch?('*.jpg', File::FNM_CASEFOLD)
        { name: child.basename.to_s, time: File.new(child).ctime }
      end
    }.compact
  end

以及将文件从保管箱移动到存储的代码:

  def self.move_claimed_image(image)
    FileUtils.move(
      Rails.configuration.dropbox_dir.join(image.original_filename),
      Rails.configuration.storage_dir.join(membership_dir(image.course, image.user), "#{image.id}.jpg")
    )
  end

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    通过调用File.new(child),您将在Ruby 中打开child 文件。打开的 File 对象(以及实际的 OS 文件句柄)将一直存在,直到该对象最终被垃圾回收,这可能需要很长时间,具体取决于内存压力。在此之前,该文件仍处于打开状态。

    要解决这个问题,您可以直接使用File.ctime class method 来获取文件的 ctime,而无需先打开文件:

    File.ctime(child)
    

    【讨论】:

    • 谢谢!这么简单的修复
    猜你喜欢
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2020-04-18
    • 1970-01-01
    • 2011-01-26
    相关资源
    最近更新 更多