user4219892
user4219892

Reputation:

Whenever cron jobs fail to run

I'm trying to use the whenever gem to run cron jobs into my application. I want to recalculate the attribute "value" of my model "User" every two minutes. Here are the steps I took:

Gemfile

gem 'whenever', :require => false

terminal

$ 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

terminal

$ whenever --update-crontab

and '$ whenever -l' returns this:

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'\'''

But so far nothing has changed in my User.values. Running User.recalculate in my console works, so the error is apparently in Whenever. What am I missing?

Upvotes: 1

Views: 2030

Answers (3)

Marc Lainez
Marc Lainez

Reputation: 3080

I quickly created a new Rails app to try to reproduce your problem, you can find it here, clone it and see for yourself.

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

First thing you will want to do is verify what environment the runner is running in. By default, whenever uses production. If you're on your local machine, be sure to set it to development in your schedule.rb or check the documentation to see how to update the crontab and set the correct environment.

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

This is what you should see in your 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'\'''

Notice it says rails runner -e development and not production.

Another thing is that basia was right. When I leave the private keyword and try to execute User.recalculate in rails c, it fails with:

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

I'm surprised it works with the private keyword in your console... You are trying to access a private method on an instance. This is not possible in Ruby. You can only access public methods of an instance from the outside (unless you use send(:method)).

Removing the private keyword fixed it and the task ran as expected every two minutes.

I'm using Rails 4.2.0 and ruby 2.1.0 in my github code.

EDIT

Make sure your cron daemon is running using:

service cron status

I also noticed that in your crontab output you have:

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

Notice the : between User and recalculate. You must have made a typo in your schedule.rb

It should be a . as it's a method call.

Also, you might wanna check that the output from whenever -l and crontab -l are the same. If crontab -l is different or empty, then you didn't use whenever --update-crontab or whenever -w correctly or something might be wrong with the whenever version you're using.

Upvotes: 4

basiam
basiam

Reputation: 1567

Remove private since right now running User.recalculate will fail with private method 'increment' called for #<User> error.

BTW, is User an ActiveRecord class? Cause there is increment http://apidock.com/rails/ActiveRecord/Base/increment method and increment! (saves record), so it might be good idea to change your method name to something else or just use user.increment!(:value).

Upvotes: 1

Arjan
Arjan

Reputation: 6274

You don't seem to be saving your user in your method increment. Try this:

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

Upvotes: 0

Related Questions