ttsesm
ttsesm

Reputation: 947

python run apschedule BlockingScheduler only once

I am using the apscheduler to schedule a specific task with an interval of 10 minutes in another thread. This works fine and I can extract also this information in the loggers that I am initiating both in the initial scheduler as well as in the other task. My problem now is when I am trying to execute the scheduler only once and then terminate it together with the application which for some reason it does not happen and the application seems to be still running (waiting for something) and thus without exiting/terminating. Below is the code snippet that I am using:

import os
import sys
import logging
from datetime import datetime
from subprocess import Popen, PIPE
from apscheduler.schedulers.blocking import BlockingScheduler

import recorder
import threading


def run_daily_sessions(thelogger):
    thelogger.info("[{}] - Trigger triggered".format(datetime.now()))
    thelogger.info("[{}] - Going to run daily scheduler script".format(datetime.now()))
    r = recorder.Recorder() # start recorder on another thread
    r.start()

    thelogger.info("[{}] - Ran daily scheduler script".format(datetime.now()))    

def main():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    handler = logging.FileHandler('scheduler.log')
    handler.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    logger.info("[{}] - scheduler.py was run".format(datetime.now()))

    sched = BlockingScheduler()
    logger.info("[{}] - blocking scheduler was created".format(datetime.now()))
    sched.add_job(run_daily_sessions, args=[logger])
    # sched.add_job(run_daily_sessions, 'interval', minutes=10, args=[logger])
    logger.info("[{}] - everyday task added, going to start the scheduler".format(datetime.now()))
    sched.start()
    # sched.shutdown()
    #logging.root.removeHandler(handler)
    return 0


if __name__ == '__main__':
    STATUS = main()
    print("terminating application!!!")
    sys.exit(STATUS)

I have tried to add max_instances=1 as a parameter to the sched.add_job() or add a sched.shutdown() but both did not work either. Then I thought that might be due to the logger instance so I've tried to remove the handler no success with that as well. So I am trying to understand why the application never reaches to print("terminating application!!!") and to exit since the scheduler has completed his task or any child tasks. My experience with threads is limited but I think that I have done things correctly following also some examples in the web thus any idea what I might be doing wrong or missing?


Solution:

thanks to @Alex Grönholm and his feedback using a job function did the trick. Snippet code:

def terminate_scheduler(thesched, thelogger, should_exit=False):
    if should_exit:
        thelogger.info('[{}] - finished scheduler... going to exit'.format(datetime.now()))
        thesched.shutdown(wait=False)

def main():
...
...
...
    sched.add_job(run_daily_sessions, args=[logger])
    sched.add_job(terminate_scheduler, args=[sched, logger, {"should_exit": True}]) # add job function for terminating scheduler
...
...
    sched.start()
...
...
    return 0

if __name__ == '__main__':
    STATUS = main()
    print("terminating application!!!")
    sys.exit(STATUS)

Upvotes: 2

Views: 7443

Answers (1)

Alex Grönholm
Alex Grönholm

Reputation: 5911

You seem to be under the impression that the scheduler should terminate on its own, implicitly, once it has no jobs left. This is an incorrect assumption. If you wish to shut down the scheduler, you must do so explicitly from another thread.

Upvotes: 2

Related Questions