我有一个名为episode
的模型的Rails 4.0.0应用程序设置,它安装了一个名为file_uploader
的载波上传器来上传mp3。我使用carrierwave_backgrounder设置了我的app设置,并使用carrierwave-ftp gem将后续文件的处理保存到sftp服务器。在我的本地机器上它很棒。同样在我的vps(CentOS 6)上,当我使用rails s
甚至rails s -e production
启动应用程序时它非常有用。但是,当我切换到nginx +乘客时,它不再按预期工作。
文件被上传到/public/uploads/tmp
dir,它们应该临时存储,但它们永远不会被移动到我指定的上传目录中,并且没有其他任何后处理内容完成,比如设置内容类型,删除缓存目录,设置文件大小和长度等。
所以,昨天,我从使用carrierwave_backgrounder命令save_in_background
切换到process_in_background
,现在它适用于本地存储的文件,但是,当我使用carrierwave-ftp gem切换到sftp存储时,文件得到处理,即它们被传输到我的sftp服务器,路径存储在我的模型中,但然后作业挂起在Resque队列中。
未执行的相关代码是:
process :set_content_type
process :save_content_type_duration_and_size_in_model
有没有人知道为什么使用开发模式甚至生产模式可以正常工作但不使用nginx +乘客呢?
以下是所有相关代码:
episode.rb:
class Episode < ActiveRecord::Base
require 'carrierwave/orm/activerecord'
# require 'mp3info'
mount_uploader :file, FileUploader
process_in_background :file
belongs_to :podcast
validates :name, :podcast, :file, presence: true
default_scope { order("created_at DESC") }
scope :most_recent, ->(max = 5) { limit(max) }
end
file_uploader.rb:
# encoding: utf-8
class FileUploader < CarrierWave::Uploader::Base
include CarrierWave::MimeTypes
include ::CarrierWave::Backgrounder::Delay
storage :sftp
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"#{model.podcast.name.to_s.downcase.parameterize}"
end
before :store, :remember_cache_id
after :store, :delete_tmp_dir
# This is the relevant code that is not getting executed
process :set_content_type
process :save_content_type_duration_and_size_in_model
def save_content_type_duration_and_size_in_model
model.content_type = file.content_type if file.content_type
model.file_size = file.size
Mp3Info.open(model.file.current_path) do |media|
model.duration = media.length
end
end
# store! nil's the cache_id after it finishes so we need to remember it for deletion
def remember_cache_id(new_file)
@cache_id_was = cache_id
end
def delete_tmp_dir(new_file)
# make sure we don't delete other things accidentally by checking the name pattern
if @cache_id_was.present? && @cache_id_was =~ /\A[\d]{8}\-[\d]{4}\-[\d]+\-[\d]{4}\z/
FileUtils.rm_rf(File.join(root, cache_dir, @cache_id_was))
end
end
end
配置/初始化/ carrierwave_backgrounder.rb:
CarrierWave::Backgrounder.configure do |c|
c.backend :resque, queue: :carrierwave
end
配置/初始化/ carrierwave.rb:
CarrierWave.configure do |config|
config.sftp_host = "ftphost.com"
config.sftp_user = "ftp_user"
config.sftp_folder = "ftp_password"
config.sftp_url = "http://url.com"
config.sftp_options = {
:password => "ftp_password",
:port => 22
}
end
我使用以下命令启动Resque:QUEUE=* bundle exec rake environment resque:work &
如果您需要更多信息,请询问。任何帮助将不胜感激。
更新:嗯,奇怪的是,通常情况下,它现在神奇地工作。不知道这个伎俩是什么,所以我担心这对任何偶然发现此页面的人都没有任何帮助。
答案 0 :(得分:0)
我有同样的问题。我的进程块在开发(rails s)中运行,但不在apache2 / passenger下运行。它并不漂亮,但我解决它的方法是将我的进程代码移动到after:cache回调中。在缓存回调之前和之后调用进程块,所以这对我来说似乎是合理的。
这是超级奇怪的部分:我不是要调用函数,我的意思是从代码块(或函数)中复制代码并直接粘贴到after_cache回调中。
我知道我做错了导致这种情况,但我无法弄清楚。希望这会对你有所帮助。
version :office_preview
# comment out the following since it does nothing under Passenger
#process :office_to_img
end
def office_to_img
this won't be called under passenger :(
end
after :cache, :after_cache
def after_cache(file)
#for some reason, calling it here doesn't do anything
#office_to_img
code copied&pasted here from office_to_img
end