【问题标题】:Schedule a one-time Resque job on heroku on application start in Rails在 Rails 中启动应用程序时在 heroku 上安排一次性 Resque 作业
【发布时间】:2014-03-24 21:20:42
【问题描述】:

我正在使用 Resque 和 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 来获取数据,然后将其更新到表中。如果我在初始化文件中添加入队方法,整个任务会发生 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

【问题讨论】:

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


    【解决方案1】:

    抽水

    首先,你为什么要在初始化时排队?

    您最好委派给从初始化程序调用的rake task

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


    问题

    我认为这行是导致问题的原因:

    Resque.enqueue(AllMessageRetriever)
    

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

    可能是错的,但这是有道理的,这意味着您的问题不在于Resque / Initializers,而是您的AllMessageRetriever 班级

    如果你能展示出来会很有帮助!

    【讨论】:

    • 嗨@RichPeck 我添加了工人类的代码。我现在已将它添加到 Rake 任务中,它工作正常。即只有一次。但唯一的问题是我必须手动调用任务并且它不会自动完成
    • 这是个好消息——也许您可以为该任务创建一个初始化程序?喜欢#config/initializers/messages.rb Rake::Task["your:task"].invoke
    猜你喜欢
    • 2023-03-05
    • 2014-08-23
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2017-05-26
    • 2011-11-11
    • 1970-01-01
    • 2017-03-25
    相关资源
    最近更新 更多