Rake任务在Heroku上超时 - 使用Sidekiq将Rake任务移动到工作人员

时间:2014-03-12 19:54:15

标签: ruby-on-rails ruby heroku sidekiq worker

我最近意识到我的佣金任务可以在Heroku上超时,而我碰巧......很多都是。

以下是我的佣金任务示例:

namespace :test do

  desc "Test Rake Task"
  task get_list: :environment do
    require 'net/ftp'
    sftp = Net::SFTP.start('ftp.test.com','luigi', :password => 'pass_word')
    records = sftp.download!("luigi/list.xml")
    records_hash = Hash.from_xml(records)
    records_hash['Report']['Details'].each do |record|
      contact = Contact.create(              
          first_name: record['FirstName'],
          last_name: record['LastName'],
          date_of_birth: record['DateofBirth']
      )
      if contact.valid?
        puts "Created contact"
      else
        puts "Invalid contact"
      end
    end    
  end
end

认为 我需要将其移至后台工作人员。循环执行此任务可能需要5分钟以上,并将每个联系人添加到数据库中。我想使用Sidekiq,但我从来没有使用过“工人”或者之前设置过它。

一般情况下,如何将Sidekiq设置为在Heroku上运行,然后将上述任务移至后台工作人员?我希望这个“工人”或“任务”每周安排一次,周一早上8点。

我的应用设置:

Procfile:

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

我正在使用postgres数据库,Rails 4.0.0,ruby 2.0.0,正如我之前提到的,我的应用程序是在Heroku上托管的。

1 个答案:

答案 0 :(得分:2)

您应该关注Sidekiq documentation并为Heroku设置。

你有Sidekiq运行,我推荐以下架构:

  • ContactListWorker:下载列表,为每个
  • 排入联系人更新作业
  • ContactWorker:提供详细信息,创建/更新联系人
  • rake task contacts:nightly_update以排队ContactListWorker作业

这里有一些粗略的伪代码来展示该架构的外观:

# rake contact:nightly_sync_list
namespace :contacts do
  desc "Test Rake Task"
  nightly_list_sync: :environment do
    ContactListWorker.perform_async
  end
end

class ContactListWorker
  require 'net/ftp'
  include Sidekiq::Worker

  def perform()
    sftp = Net::SFTP.start('ftp.test.com','luigi', :password => 'pass_word')
    records = sftp.download!("luigi/list.xml")
    records_hash = Hash.from_xml(records)
    records_hash['Report']['Details'].each {|record| ContactWorker.perform_async(record) }
  end
end

class ContactWorker
  include Sidekiq::Worker

  def perform(record)
    contact = Contact.create(
      first_name: record['FirstName'],
      last_name: record['LastName'],
      date_of_birth: record['DateofBirth']
    )
    if contact.valid?
      puts "Created contact"
    else
      puts "Invalid contact"
    end
 end

此架构允许您异步启动一个后台ContactListWorker作业。此作业将执行下载并快速异步排队N ContactWorker个作业。这允许您在多个Sidekiq工作者和线程之间扇出处理以分发处理。