rq/Flask-RQ2

Why does func.cron() not duplicate jobs but rq.get_scheduler().cron() does?

kennysong opened this issue · 1 comments

I'm using Flask-RQ2 behind Gunicorn, which creates (let's say) 2 worker processes of the Flask app.

Each Flask app schedules a RQ cron job inside the create_app() factory. Because there are 2 worker processes, the same cron job is scheduled twice.

When I use:

@rq.job
def example_job():
    with open('./example_job_log.txt', 'a') as f:
        f.write(f'Example job ran at: {datetime.datetime.now()}\n')

example_job.cron('* * * * *', 'example_job')

Then the example_job.cron() line runs twice, but the job is NOT duplicated. example_job runs once a minute.

However, if I use:

def example_job():
    with open('./example_job_log.txt', 'a') as f:
        f.write(f'Example job ran at: {datetime.datetime.now()}\n')

scheduler = rq.get_scheduler()
scheduler.cron('* * * * *', func=example_job)

Then example_job is duplicated and runs twice a minute. Why is this the case?

For anyone else wondering about this, I believe the answer is that example_job.cron('* * * * *', 'example_job') actually calls rq.get_scheduler().cron(...) with an id parameter for the cron job.

rq-scheduler then deduplicates cron jobs with the same id. So the second example should work if you do:

def example_job():
    with open('./example_job_log.txt', 'a') as f:
        f.write(f'Example job ran at: {datetime.datetime.now()}\n')

scheduler = rq.get_scheduler()
scheduler.cron('* * * * *', func=example_job, id='example_job')

(Note: the rq-scheduler id and the rq queue job_id are handled differently. You can enqueue as many jobs as you want with the same job_id, and all of them will run.)