系统是否“...”还在 Heroku Cedar / Rails 3.1 上工作吗?

发布于 2024-12-05 13:00:00 字数 509 浏览 2 评论 0原文

我使用 Railscast 127 中的 RyanB 技术在后台运行几个 rake 任务,它在本地和 Rails 3 上运行良好,但在 Heroku 的 cedar stack 生产中的 3.1 上运行不佳。在我将它们删除并用delayed_job替换它们之前,这种分叉进程的方法是否仍然有效?

  def call_rake(task, options = {})
    options[:rails_env] ||= Rails.env
    args = options.map { |n, v| "#{n.to_s.upcase}='#{v}'" }
    system "rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
  end

I have a couple of rake tasks run in the background using RyanB's technique from Railscast 127, which work fine locally and on Rails 3, but not on 3.1 in production on Heroku's cedar stack. Before I rip them out and replace them with delayed_job, should this method of forking a process still work?

  def call_rake(task, options = {})
    options[:rails_env] ||= Rails.env
    args = options.map { |n, v| "#{n.to_s.upcase}='#{v}'" }
    system "rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
  end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情魔剑神 2024-12-12 13:00:00

在深入研究之后,我自己回答了这个问题:系统位可以,但 & 不可以。 Delayed_job 就是解决这个问题的方法。 FWIW 这是我的工作代码,使用 Heroku 的 Cedar 堆栈上的elasted_job 在 Rails 3.1 应用程序中运行 rake 任务,生成 XML 文件,将其保存到临时文件,然后上传到 S3。 XML 输出文件很大,因此需要异步处理它。

app/classes/callrake.rb:

class Callrake
  def call_rake(task, options = {})
      options[:rails_env] ||= Rails.env
      args = options.map { |n, v| "#{n.to_s.upcase}='#{v}'" }
      system "rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log"

    end
  handle_asynchronously :call_rake
end

isbns 控制器:

def onixtwo 
#using Ransack, successor to Metasearch
  @q = Isbn.where(:client_id => current_user.client_id).search(params[:q])
   @isbns = @q.result(:distinct => true)
  if @q.nil? 
     @isbns = Isbn.where(:client_id => current_user.client_id)
  end
  #I have an array to pass so this is a bit hacky - make an array, pass it as a string then turn it back into an array using eval()
  is = []
  @isbns_to_pass = @isbns.each {|isbn| is << isbn.id }
  @client = current_user.client_id   
  @user = current_user.id
  callrake = Callrake.new
  callrake.call_rake(:onixtwo, :isbns => is, :client => @client, :user => @user)
  redirect_to isbns_path, :flash => { :notice => t(:isbnonixtwo).html_safe }

end

为了完整性,稍微偏离主题的 config/locales/en.yml:

en:
  isbnonixtwo: "Onix 2.1 message is generating. When it's done, you can download it from the <a href='/onixarchives'>Onix Archive</a> list."

rake 任务:

desc "Generate an onix 2.1 xml file"
task :onixtwo => :environment do |t|


  client_id = ENV["CLIENT"]
  user_id = ENV["USER"]
  isbns_passed = ENV["ISBNS"]
  isbnsarray = eval(isbns_passed)
  filename = "#{Rails.root}/public/#{Client.find_by_id(client_id).client_name}-#{Date.today}-#{Time.now}-onix-21.xml"    
  isbns = Isbn.find_all_by_id(isbnsarray)

 File.open(filename, "w") do |file|

    xml = Builder::XmlMarkup.new(:target => file, :indent => 2)
    xml.instruct!(:xml, :version => "1.0", :encoding => "utf-8")
    xml.declare! :DOCTYPE, :ONIXMessage, :SYSTEM, "http://www.editeur.org/onix/2.1/03/reference/onix-international.dtd"
    xml.ONIXMessage do
      xml.Header do 
#masses of code

  end  #of file 
  xmlfile = File.open(filename, "r")
  onx = Onixarchive.new(:client_id => client_id, :user_id => user_id) 
  onx.xml = xmlfile
  onx.save!
  end #of task

然后 Onixarchive 在模型中设置了常规的回形针附件。

请注意文件路径中的 Rails.root.public - 当我尝试写入 app/tmp 时,我不断收到“不存在”的消息,因为,当我使用 heroku 的控制台查看时,果然没有 tmp 文件夹。我想我可以创建一个,但这个应用程序是在 cedar 上,它有一个 临时文件系统< /a> 这样您就可以在会话期间的任何地方进行写入。

Answering this myself, after digging around: the system bit does but not the &. Delayed_job is the way to go on this. FWIW here's my working code to run a rake task in a rails 3.1 app using delayed_job on Heroku's Cedar stack, to generate an XML file, save it to temp then upload to S3. The XML output file is large, hence the need to handle it asynchronously.

app/classes/callrake.rb:

class Callrake
  def call_rake(task, options = {})
      options[:rails_env] ||= Rails.env
      args = options.map { |n, v| "#{n.to_s.upcase}='#{v}'" }
      system "rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log"

    end
  handle_asynchronously :call_rake
end

isbns controller:

def onixtwo 
#using Ransack, successor to Metasearch
  @q = Isbn.where(:client_id => current_user.client_id).search(params[:q])
   @isbns = @q.result(:distinct => true)
  if @q.nil? 
     @isbns = Isbn.where(:client_id => current_user.client_id)
  end
  #I have an array to pass so this is a bit hacky - make an array, pass it as a string then turn it back into an array using eval()
  is = []
  @isbns_to_pass = @isbns.each {|isbn| is << isbn.id }
  @client = current_user.client_id   
  @user = current_user.id
  callrake = Callrake.new
  callrake.call_rake(:onixtwo, :isbns => is, :client => @client, :user => @user)
  redirect_to isbns_path, :flash => { :notice => t(:isbnonixtwo).html_safe }

end

slightly off-topic config/locales/en.yml for completeness:

en:
  isbnonixtwo: "Onix 2.1 message is generating. When it's done, you can download it from the <a href='/onixarchives'>Onix Archive</a> list."

rake task:

desc "Generate an onix 2.1 xml file"
task :onixtwo => :environment do |t|


  client_id = ENV["CLIENT"]
  user_id = ENV["USER"]
  isbns_passed = ENV["ISBNS"]
  isbnsarray = eval(isbns_passed)
  filename = "#{Rails.root}/public/#{Client.find_by_id(client_id).client_name}-#{Date.today}-#{Time.now}-onix-21.xml"    
  isbns = Isbn.find_all_by_id(isbnsarray)

 File.open(filename, "w") do |file|

    xml = Builder::XmlMarkup.new(:target => file, :indent => 2)
    xml.instruct!(:xml, :version => "1.0", :encoding => "utf-8")
    xml.declare! :DOCTYPE, :ONIXMessage, :SYSTEM, "http://www.editeur.org/onix/2.1/03/reference/onix-international.dtd"
    xml.ONIXMessage do
      xml.Header do 
#masses of code

  end  #of file 
  xmlfile = File.open(filename, "r")
  onx = Onixarchive.new(:client_id => client_id, :user_id => user_id) 
  onx.xml = xmlfile
  onx.save!
  end #of task

Then Onixarchive has a regular paperclip attachment set-up in the model.

Note the Rails.root.public in the filepath - I kept getting a "does not exist" when I tried to write to app/tmp, because, sure enough when I looked using heroku's console, there is no tmp folder. I suppose I could have created one, but this app is on cedar, which has an ephemeral filesystem so you can write anywhere for the duration of the session.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文