每当 cron 作业失败时 运行

Whenever cron jobs fail to run

我正在尝试在我的应用程序中使用 whenever gem 到 运行 cron 作业。我想每两分钟重新计算模型 "User" 的属性 "value"。以下是我采取的步骤:

Gemfile

gem 'whenever', :require => false

终端机

$ bundle install
$ wheneverize .

schedule.rb

every 2.minutes do
  runner "User.recalculate"
end

models/user.rb

def self.recalculate
  User.all.each {|user| user.recalculate_value }
end

private

def recalculate_value
  self.value = self.value + 1
  self.save!
end

终端机

$ whenever --update-crontab

和'$ whenever -l'returns这个:

0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * * /bin/bash -l -c 'cd /home/website && bin/rails runner -e development '\''User:recalculate'\'''

但到目前为止,我的 User.values 没有任何变化。 运行 User.recalculate 在我的控制台中工作,所以错误显然是在任何时候。我错过了什么?

您似乎没有在您的方法中保存您的用户 increment。试试这个:

def increment
  self.value = self.value + 1
  self.save
end

删除 private 因为现在 运行 User.recalculate 将失败并出现 private method 'increment' called for #<User> 错误。

顺便说一句,用户是 ActiveRecord class 吗?因为有 increment http://apidock.com/rails/ActiveRecord/Base/increment 方法和 increment!(保存记录),所以最好将方法名称更改为其他名称或只使用 user.increment!(:value).

我很快创建了一个新的 Rails 应用程序来尝试重现您的问题,您可以在这里找到它,克隆它并亲自看看。

https://github.com/mlainez/Whosebug-28111330/blob/master/app/models/user.rb

您要做的第一件事是验证运行器 运行 所在的环境。默认情况下,无论何时使用 production。如果您在本地计算机上,请务必在 schedule.rb 中将其设置为 development 或查看文档以了解如何更新 crontab 并设置正确的环境。

https://github.com/mlainez/Whosebug-28111330/blob/master/config/schedule.rb#L7

这是您应该在 crontab 中看到的内容:

0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * * /bin/bash -l -c 'cd /Users/marc/Projects/stack && bin/rails runner -e development '\''User.recalculate'\'''

注意它说 rails runner -e development 而不是 production

另一件事是basia是对的。当我离开 private 关键字并尝试在 rails c 中执行 User.recalculate 时,它失败了:

private method `recalculate_value' called for #<User ...>

我很惊讶它在您的控制台中使用 private 关键字...您正在尝试访问实例上的私有方法。这在 Ruby 中是不可能的。您只能从外部访问实例的 public 方法(除非您使用 send(:method))。

删除 private 关键字修复了它和任务 运行 每两分钟一次。

我在 github 代码中使用 Rails 4.2.0 和 ruby 2.1.0。

编辑

确保你的 cron 守护进程 运行 使用:

service cron status

我还注意到在您的 crontab 输出中您有:

bin/rails runner -e development '\''User:recalculate'\''

注意 Userrecalculate 之间的 :。您一定是在 schedule.rb

中打错了字

它应该是一个 . 因为它是一个方法调用。

此外,您可能想检查 whenever -lcrontab -l 的输出是否相同。如果 crontab -l 不同或为空,则说明您没有正确使用 whenever --update-crontabwhenever -w,或者您使用的版本可能有问题。