Python - Apscheduler not stopping a job even after using 'remove_job'
Asked Answered
P

4

6

This is my code

I'm using the remove_job and the shutdown functions of the scheduler to stop a job, but it keeps on executing.

What is the correct way to stop a job from executing any further?

from apscheduler.schedulers.background import BlockingScheduler

def job_function():
    print "job executing"


scheduler = BlockingScheduler(standalone=True)
scheduler.add_job(job_function, 'interval', seconds=1, id='my_job_id')


scheduler.start()
scheduler.remove_job('my_job_id')
scheduler.shutdown()
Papst answered 9/10, 2015 at 10:48 Comment(0)
P
18

Simply ask the scheduler to remove the job inside the job_function using the remove_function as @Akshay Pratap Singh Pointed out correctly, that the control never returns back to start()

from apscheduler.schedulers.background import BlockingScheduler

count = 0

def job_function():
    print "job executing"
    global count, scheduler

    # Execute the job till the count of 5 
    count = count + 1
    if count == 5:
        scheduler.remove_job('my_job_id')


scheduler = BlockingScheduler()
scheduler.add_job(job_function, 'interval', seconds=1, id='my_job_id')


scheduler.start()
Papst answered 11/10, 2015 at 11:41 Comment(0)
C
8

As you are using BlockingScheduler , so first you know it's nature.

So, basically BlockingScheduler is a scheduler which runs in foreground(i.e start() will block the program).In laymen terms, It runs in the foreground, so when you call start(), the call never returns. That's why all lines which are followed by start() are never called, due to which your scheduler never stopped.

BlockingScheduler can be useful if you want to use APScheduler as a standalone scheduler (e.g. to build a daemon).


Solution

If you want to stop your scheduler after running some code, then you should opt for other types of scheduler listed in ApScheduler docs.

I recommend BackgroundScheduler, if you want the scheduler to run in the background inside your application/program which you can pause, resume and remove at anytime, when you need it.

Celsacelsius answered 9/10, 2015 at 11:36 Comment(4)
The Code does'nt execute a single job at all, when using BackgroundScheduler this way -> pastebin.com/xDAJAXvT What am i doing wrong?Papst
With BackgroundScheduler, start() does not block so your main script ENDS, effectively stopping your application. Surely you don't want to stop the job right after starting the scheduler, so what is the real world scenario here?Intermigration
@AlexGrönholm I simply want to schedule a job running every interval, even if the main script ends. I'd like to stop the job eventually inside the associated functionPapst
I think the other option is to throw it in a try/catch and look for specific exceptions (like keyboard interrupt) to stop the scheduler.Deaden
C
2

This is how I solved the problem. Pay attention to the position where the code schedule.shutdown() is located!

def do_something():
    global schedule
    print("schedule execute")
    # schedule.remove_job(id='rebate')
    schedule.shutdown(wait=False)


if __name__ == '__main__':
    global schedule
    schedule = BlockingScheduler()
    schedule.add_job(do_something, 'cron', id='rebate', month=12, day=5, hour=17, minute=47, second=35)
    schedule.start()
    print('over')
Carminacarminative answered 5/12, 2021 at 9:55 Comment(1)
worked for me alsoDehydrogenase
M
0

The scheduler needs to be stopped from another thread. The thread in which scheduler.start() is called gets blocked by the scheduler. The lines that you've written after scheduler.start() is unreachable code.

Milker answered 6/4, 2016 at 22:16 Comment(1)
please clarify what additional value ad given by this post from others.Abbreviate

© 2022 - 2025 — McMap. All rights reserved.