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()
wolfgang
  • 7,281
  • 12
  • 44
  • 72

4 Answers4

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()
wolfgang
  • 7,281
  • 12
  • 44
  • 72
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.

Akshay Pratap Singh
  • 3,197
  • 1
  • 24
  • 33
  • The Code does'nt execute a single job at all, when using BackgroundScheduler this way -> http://pastebin.com/xDAJAXvT What am i doing wrong? – wolfgang Oct 09 '15 at 14:03
  • 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? – Alex Grönholm Oct 09 '15 at 20:45
  • @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 function – wolfgang Oct 10 '15 at 06:50
  • 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. – swade Feb 07 '19 at 01:09
1

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')
ouflak
  • 2,458
  • 10
  • 44
  • 49
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.

dungeon_master
  • 191
  • 1
  • 1
  • 8