Konrad
Konrad

Reputation: 902

APScheduler jobs run several times when jobs are set to be run at the same time

I want to schedule and run jobs using APScheduler and the cron format.

from apscheduler.schedulers.background import BackgroundScheduler

def test_func():
    print("Test job func")

scheduler = BackgroundScheduler()

today_str = datetime.today().strftime('%Y-%m-%d')
today_with_time = datetime.strptime(today_str + " " + "12:07:00", "%Y-%m-%d %H:%M:%S")

scheduler.add_job(
                test_func,
                "cron",
                id="test",
                name="test",
                day_of_week="2",
                hour=today_with_time.hour,
                minute=today_with_time.minute,
                replace_existing=False)

Let's say I do this twice, with two different job IDs. There are two jobs, set to run at the exact same time. With one job, it runs once as expected. With two jobs, it runs 4 times. The same happens with other triggers such as DateTrigger.

Note that this is set-up within a Flask app. Normally, the app makes a call to another API to fetch jobs, then schedules them one by one.

EDIT: my actual app fetches 3 jobs and schedules them, all at the same time. When I fetch 1 job instead of 3, the bug does not occur. When I have 3 jobs, the function is run 9 times. With 1 job, it is run once.

Upvotes: 1

Views: 5743

Answers (3)

Saurabh
Saurabh

Reputation: 26

I have gotten the similar issue, as in my case I was initializing the scheduler whenever I am adding new job to it.

solution:

create separate function or class, which initialize/call only once and use the scheduler object wherever you are using job operations eg: add, pause, resume etc

code snippet:

def initialize_scheduler():

    sched = BackgroundScheduler(daemon=False)
    job_store = MongoDBJobStore(database=db.name,
                                collection='scheduler', client=client,
                                pickle_protocol=4)
    sched.add_jobstore(jobstore=job_store, alias='mongodb')
    sched.start()

    return sched

the above sched var will be used every where.

Upvotes: 0

Konrad
Konrad

Reputation: 902

It turns out I was a genius and initialized a scheduler every time a job was fetched. :-]

So now, I changed the class that manages scheduling (and initializes the scheduler) to a singleton and it works as expected.

Upvotes: 0

Yassine Faris
Yassine Faris

Reputation: 991

It's because Flask initialize twice on debug mode.

Short answers: app.run(debug=True, use_reloader=False)

Full answers here: How to stop Flask from initialising twice in Debug Mode?

Upvotes: 0

Related Questions