在Rails中的应用程序启动时在heroku上安排一次性Resque作业

时间:2014-02-23 10:20:49

标签: ruby-on-rails heroku ruby-on-rails-4 resque resque-scheduler

我正在使用Resque and Resque Schedule来启动必须在应用程序启动时立即运行的作业。其他预定作业每30秒加载一次。

这是我的config / initializers / redis.rb的代码

require 'rake'
require 'resque'
require 'resque/server'
require 'resque_scheduler/tasks'
# This will make the tabs show up.
require 'resque_scheduler'
require 'resque_scheduler/server'

uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Resque.redis = REDIS
Dir["#{Rails.root}/app/workers/*.rb"].each { |file| require file }
Resque.enqueue(AllMessageRetriever)
Resque.schedule = YAML.load_file(Rails.root.join('config', 'schedule.yml'))

启动应用程序时,AllMessageRetriever将运行2-3次而不是仅运行一次。初始化器是否被多次调用?在Heroku和我当地的环境中都会发生这种情况吗?

是否可以在Resque-Scheduler中设置延迟作业,该作业只会在运行时立即执行一次?

AllMessageRetriever的代码。基本上它循环遍历表并调用外部API来获取数据,然后将其更新到表中。如果我在初始化文件

中添加enqueue方法,则整个任务会发生2-3次
 require 'socialcast'
module AllMessageRetriever
    @queue = :message_queue
    def self.perform()
        Watchedgroup.all.each do |group|    
            puts "Running group #{group.name}"
            continueLoading=true
            page=1
            per_page=500
            while(continueLoading == true)
                User.first.refresh_token_if_expired
                token = User.first.token
                puts "ContinueLoading: #{continueLoading}"
                @test = Socialcast.get_all_messages(group.name,token,page,per_page)

                messagesArray =  ActiveSupport::JSON.decode(@test)["messages"]
                puts "Message Count: #{messagesArray.count}"
                if messagesArray.count == 0
                    puts 'count is zero now'
                    continueLoading = false
                else
                    messagesArray.each do |message|
                        if not Message.exists?(message["id"])   
                            Message.create_with_socialcast(message, group.id)
                        else
                            Message.update_with_socialcast(message)
                        end
                    end
                end
                page += 1
            end
            Resqueaudit.create({:watchedgroup_id => group.id,:timecompleted => DateTime.now})
        end
        # Do anything here, like access models, etc
        puts "Doing my job"
    end
end

1 个答案:

答案 0 :(得分:1)

<强>耙

首先,你为什么要尝试在init上排队?

您可以更好地委托从初始化程序调用的rake task

这将删除对初始化过程的依赖,这应该清除很多东西。我不会把它放在初始化器本身,因为它会更好地处理其他地方(modularity


<强>问题

我认为这一行造成了这个问题:

Resque.enqueue(AllMessageRetriever)

在没有看到AllMessageRetriever的内容的情况下,我猜测你是AllMessageRetriever(模块/类?)将返回结果2/3次,导致Resque添加(2) / 3次)数据设置到队列

可能是错的,但这有意义,并且意味着您的问题不在于Resque / Initializers,而在于您的AllMessageRetriever

如果你展示它会有很大的帮助!