Руфус планировщик работает дважды каждый раз

Может быть, это моя задача, может быть, это мой планировщик, но по какой-то причине моя запланированная задача выполняется дважды или сохраняет две версии в БД. Вот мой код:

report.rb:

  def record_page_stats!
    oauth = Koala::Facebook::OAuth.new
    @api = Koala::Facebook::API.new oauth.get_app_access_token
    @fb_page = @api.get_object(self.fb_page_id)
    self.page_stats.new(like_count: @fb_page["likes"], talking_about_count: @fb_page["talking_about_count"])
    self.save
  end

И scheduler.rb:

require 'rufus-scheduler'

scheduler = Rufus::Scheduler.new

scheduler.every '10m' do
  Report.where(tracking_page: true).each do |report|
    report.record_page_stats!
  end
end

я пропускаю что-то действительно очевидное? вот вывод из базы данных сохраненной статистики страниц:

2013-12-20 18:43:06 UTC = 8304 likes and 229 talking about count 
2013-12-20 18:43:08 UTC = 8304 likes and 229 talking about count 
2013-12-20 18:53:06 UTC = 8304 likes and 229 talking about count 
2013-12-20 18:53:08 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:03:06 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:03:08 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:13:06 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:13:08 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:23:07 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:23:33 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:33:06 UTC = 8304 likes and 229 talking about count 
2013-12-20 19:33:32 UTC = 8304 likes and 229 talking about count 

как видно из отметки времени, она запускается дважды каждые 10 минут

РЕДАКТИРОВАТЬ:

Я просто посмотрел на данные еще раз... и планировщик изменил время несколько раз:

  1. во-первых, он выполнял работу два раза подряд, каждые 10 минут
  2. затем он переключается на один раз в 10 минут
  3. затем он переключается на один раз в 5 минут
  4. затем он переключился на два раза в 5 минут

РЕДАКТИРОВАТЬ 2: новый вывод после блокировки:

2013-12-20 22:14:22 UTC = 176155 likes and 5757 talking about count 
2013-12-20 22:14:24 UTC = 176155 likes and 6994 talking about count 

Мой файл теперь выглядит так:

require 'rufus-scheduler'

scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler.lock")

scheduler.every '10m' do
  Report.where(tracking_page: true).each do |report|
    report.record_page_stats!
  end
  log "started Scheduler #{scheduler.object_id}"
end

однако в логах героку есть ошибка:

2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440   job:
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440     Rufus::Scheduler::EveryJob "10m" {}
2013-12-20T22:44:42.625951+00:00 app[worker.1]: { 70149016354440 rufus-scheduler intercepted an error:
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440   error:
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440     70149016354440
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440     ArgumentError
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440     wrong number of arguments (1 for 0)
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/yard-0.8.7.3/lib/yard/globals.rb:16:in `log'
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:224:in `call'
2013-12-20T22:44:42.626163+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:224:in `do_trigger'
2013-12-20T22:44:42.626163+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:269:in `block (3 levels) in start_work_thread'
2013-12-20T22:44:42.626163+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:272:in `call'
2013-12-20T22:44:42.626163+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:272:in `block (2 levels) in start_work_thread'
2013-12-20T22:44:42.626163+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:258:in `loop'
2013-12-20T22:44:42.626163+00:00 app[worker.1]:   70149016354440       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:258:in `block in start_work_thread'
2013-12-20T22:44:42.626163+00:00 app[worker.1]: } 70149016354440 .
2013-12-20T22:44:42.625951+00:00 app[worker.1]:   70149016354440       /app/config/initializers/scheduler.rb:9:in `block in <top (required)>'
2013-12-20T22:44:44.472460+00:00 app[web.1]: { 69970029016200 rufus-scheduler intercepted an error:
2013-12-20T22:44:44.472460+00:00 app[web.1]:   69970029016200   job:
2013-12-20T22:44:44.472460+00:00 app[web.1]:   69970029016200     Rufus::Scheduler::EveryJob "10m" {}
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200     ArgumentError
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200     wrong number of arguments (1 for 0)
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/yard-0.8.7.3/lib/yard/globals.rb:16:in `log'
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:224:in `call'
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:224:in `do_trigger'
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:269:in `block (3 levels) in start_work_thread'
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:272:in `call'
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:272:in `block (2 levels) in start_work_thread'
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:258:in `loop'
2013-12-20T22:44:44.473000+00:00 app[web.1]:   69970029016200       /app/vendor/bundle/ruby/2.0.0/gems/rufus-scheduler-3.0.3/lib/rufus/scheduler/jobs.rb:258:in `block in start_work_thread'
2013-12-20T22:44:44.472460+00:00 app[web.1]:   69970029016200   error:
2013-12-20T22:44:44.472460+00:00 app[web.1]:   69970029016200     69970029016200
2013-12-20T22:44:44.472615+00:00 app[web.1]:   69970029016200       /app/config/initializers/scheduler.rb:9:in `block in <top (required)>'
2013-12-20T22:44:44.473000+00:00 app[web.1]: } 69970029016200 .

2 ответа

Решение

Итак, в соответствии с тегами, которые вы поместили в свой вопрос, вы используете Ruby on Rails.

У меня сложилось впечатление, что у вас работает два планировщика (один был инициализирован через 2 секунды после первого, как намекает вывод журнала).

Вы можете легко разместить что-то вроде

log "started Scheduler #{scheduler.object_id}"

после инициализации планировщика, чтобы увидеть, что происходит.

Вы не упоминаете, на чем вы работаете с Rails (Webrick, Passenger, Thin, Unicorn, ...?). Некоторые из них запускают несколько копий процесса Rails.

Вы можете использовать систему блокировки в rufus-scheduler, чтобы предотвратить запуск второго (или третьего...) планировщика.

Для простого блокировочного механизма: https://github.com/jmettraux/rufus-scheduler/

Если вам нужно больше (возможно, запуск нескольких Rails на разных хостах): https://github.com/jmettraux/rufus-scheduler/

Варианты, которые вы видите в своем EDIT, вероятно, связаны с сервером, разрабатывающим новые копии Rails, чтобы справиться со спросом.

Итак, вы на Heroku.

Это может помочь: https://devcenter.heroku.com/articles/clock-processes-ruby

Если вы зайдете немного в Google или поищете в документации по heroku, вы найдете другие места, где они объясняют, как запускать специальные процессы, помимо процесса Rails, для таких вещей, как планировщик и фоновые рабочие.

Это также может помочь: https://devcenter.heroku.com/articles/procfile

Другие вопросы по тегам