关注Bate的Railscast(http://railscasts.com/episodes/127-rake-in-background)关于后台任务,尝试使用一些邮件程序,而不是为我工作。
应用程序控制器:
def call_rake(task, options = {})
options[:rails_env] ||= Rails.env
args = options.map { |n, v| "#{n.to_s}='#{v}'" }
system "rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
# need to add path to rake /usr/bin/rake, etc.
end
请求控制器:
call_rake :connect_email, :requestrecord => @requestrecord, :lender_array => @lender_array, :item => item, :quantity => quantity
Rake connect_email.rb:
desc "Send email to connect borrower/lender pairs for items found"
task :connect_email => :environment do
RequestMailer.found_email(requestrecord, lender_array, item, quantity).deliver unless lender_array.blank?
end
主要的错误NameError: undefined local variable or method
lender_array':对象. Funny thing is, on a different mailer where the same parameters are passed except for
lender_array , I get an error message
NameError:未定义的局部变量或方法requestrecord' for main:Object
。
对于为什么有任何想法?
由于这是我第一次做背景任务,所以希望能够从聪明人那里获得更多见解:
/usr/bin/rake
,如何在本地机器和生产中找到它的路径? (使用Heroku)rake.log
文件中注册。它是否仅在动作完成时注册(即成功)?我只是在想,如果A人做了调用rake电子邮件的动作,然后B人做了同样的动作,几秒钟之后就会调用rake电子邮件,Rails会首先为A人执行rake任务然后做人B请求,然后做人B的佣金任务,或者做人A请求,B人请求,然后按照收到的顺序执行佣金任务,只要实际请求有停机时间?
谢谢!
答案 0 :(得分:0)
问题中有很多问题,我首先会告诉你代码的问题,当你运行rake任务时,执行的代码是:
task :connect_email => :environment do
RequestMailer.found_email(requestrecord, lender_array, item, quantity).deliver unless lender_array.blank?
end
所以当执行该代码时,不会定义requesterecord,lender_array,item和quantity。这是纯粹的红宝石代码。如果您详细检查截屏视频,它传递给rake任务的是环境变量/值,而不是ruby变量,正确的代码是:
task :connect_email => :environment do
RequestMailer.found_email(ENV["requestrecord"], ENV["lender_array"], ENV["item"], ENV["quantity"]).deliver unless lender_array.blank?
end
现在,如果您执行该代码,它也不会工作,因为所有环境变量都是由ruby接收为String,因此您必须将它们转换为所需类型的变量。 如果你打电话给代码:
call_rake :connect_email, lender_array: ['hello', 'world']
它会将环境变量 lender_array 设置为' [" hello"," world"]',这将被收到通过 connect_email 任务作为ruby字符串,如果要将其转换为Ruby数组,可以执行以下操作:
RequestMailer.found_email(ENV["requestrecord"], eval(ENV["lender_array"]))
因为如果您评估字符串' [" hello"," world"]',它将被评估为Ruby Array。
答:是的,每次运行任务时,它都会在新进程中从零开始初始化rails,是的,它很昂贵。
答:您可以为此设置环境变量,这在heroku中设置环境变量很常见,即您可以设置环境变量RAKE_PATH =" / usr / bin / rake"然后在你的代码上你可以做到:
system "#{ENV['RAKE_PATH'} #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
答:不,每次运行rake任务时,都会创建一个不同的进程来运行该特定任务,而不是队列。
答:Rake任务通常记录信息,我不确定为什么该异常没有被记录,但我通常检查日志,我看到rake任务正在运行并记录到它们。
为了能够在后台执行更好的任务,您可以检查delayed_job,其中存储要在数据库上运行的作业,然后守护程序获取任务并在后台运行它们。 / p>