Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

same crontab on multiple servers #598

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

bernabas
Copy link

@bernabas bernabas commented Dec 5, 2015

I have exported whenever tasks on multiple servers, but most of the crontab tasks have an implicit assumption that they should only be run once in their given time frame. Having multiple servers with the same crontab tasks obviously would break this assumption, leading to all kinds of weird bugs. Instead, what if we let the servers use a middleware (in this implementation, redis is used) to communicate and decide which server will run the task.

in *.schedule.rb

set :redis_options, url: 'redis://localhost:6379/1'

the default value for :redis_options is nil

and if it is set to something other than nil, instead of

0 4 * * * /bin/bash -l -c 'cd /path && bundle exec rake sometask --silent >> log/cron.log 2>> log/cron-error.log' 

it would export

0 4 * * * /bin/bash -l -c 'cd /path && if whenever_server >> /dev/null ; then cd /path && bundle exec rake sometask --silent >> log/cron.log 2>> log/cron-error.log ; fi'

before executing the job, we would execute the whenever_server script that would basically use atomic operations to decide if the job should run on this server on not (guaranteeing that the job is executed only once)

@bernabas
Copy link
Author

bernabas commented Dec 5, 2015

@javan can you take a look when you have time?
thanks 😃

@sandstrom
Copy link

sandstrom commented Jun 1, 2017

I think it would be better if whenever exposed a simple locking mechanism.

# schedule.rb

acquire_lock do
  # The user can decide what to do here, for example make an http request, 
  # inquiry with redis, check with consul, or use some other mechanism.

  # If this method return true whenever will run the job/task/item.
  # If defined, this block is invoked before every runner/task in the schedule.
  true
end

Base automatically changed from master to main January 20, 2021 18:17
@ausangshukla
Copy link

How are people handling this? I too have the exact same issue.

@sandstrom
Copy link

sandstrom commented May 15, 2024

@ausangshukla I would look at https://github.com/rails/solid_queue or https://github.com/bensheldon/good_job, both have support for scheduled jobs AFAIK.

If you want to use whenever, handle the locking outside, i.e. in application code in your job. For example like this: https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants