将参数传递给Rake未找到

时间:2014-07-07 03:16:32

标签: ruby-on-rails heroku ruby-on-rails-4 rake background-process

关注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

对于为什么有任何想法?

由于这是我第一次做背景任务,所以希望能够从聪明人那里获得更多见解:

  1. 如果每次运行此任务时都加载环境,那么是不是非常昂贵?我的意思是,这意味着每小时可以多次重新加载环境......
  2. Ryan提到了具体的rake路径是个好主意,例如/usr/bin/rake,如何在本地机器和生产中找到它的路径? (使用Heroku)
  3. 说正在发生的事情是Rails按照控制器调用的顺序排队Rake任务列表是否正确,然后一旦请求完成,只需逐个执行它们?
  4. 这些错误消息都没有在我创建的rake.log文件中注册。它是否仅在动作完成时注册(即成功)?
  5. 我只是在想,如果A人做了调用rake电子邮件的动作,然后B人做了同样的动作,几秒钟之后就会调用rake电子邮件,Rails会首先为A人执行rake任务然后做人B请求,然后做人B的佣金任务,或者做人A请求,B人请求,然后按照收到的顺序执行佣金任务,只要实际请求有停机时间?

    谢谢!

1 个答案:

答案 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。


  1. 如果每次运行此任务时都会加载环境,那么这不是非常昂贵吗?我的意思是,这意味着每小时可以多次重新加载环境......
  2. 答:是的,每次运行任务时,它都会在新进程中从零开始初始化rails,是的,它很昂贵。

    1. Ryan提到了特定rake路径的好主意,例如/ usr / bin / rake,如何在本地机器上以及生产中找到它的路径? (使用Heroku)
    2. 答:您可以为此设置环境变量,这在heroku中设置环境变量很常见,即您可以设置环境变量RAKE_PATH =" / usr / bin / rake"然后在你的代码上你可以做到:

      system "#{ENV['RAKE_PATH'} #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
      
      1. 说正是发生的事情是Rails按照控制器调用的顺序排队Rake任务列表是正确的,然后一旦请求完成,只需执行它们一个接一个<?/ LI>

        答:不,每次运行rake任务时,都会创建一个不同的进程来运行该特定任务,而不是队列。

        1. 这些错误消息都没有在我创建的rake.log文件中注册。它是否仅在动作完成时注册(即成功)?
        2. 答:Rake任务通常记录信息,我不确定为什么该异常没有被记录,但我通常检查日志,我看到rake任务正在运行并记录到它们。


          为了能够在后台执行更好的任务,您可以检查delayed_job,其中存储要在数据库上运行的作业,然后守护程序获取任务并在后台运行它们。 / p>