I'm working on a project to run Python APScheduler as a Windows Service with the results going to a text file. I can install and start the service without a hitch.
I've tried a couple of ways of running the scheduler inside a service with the most common and frustrating result being that when I stop the service the scheduler's thread continues to write to the text file. I have to reboot the computer to kill the thread.
I've tried a 'blocking' and 'background' schedulers and they behave the same.
I've played with moving the scheduler.shutdown() into different places. I would like to place it in the service stop function and have the scheduler run until the service receives a stop command whereupon the service stop function would handle shutting down the scheduler.
Perhaps you can point me in the right direction? Here is the code sanitized to ensure you will not have to reboot your computer.
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import logging
import configparser
import os
from datetime import datetime
from mysql.connector import errorcode
from apscheduler.schedulers.background import BackgroundScheduler
global FILEPATH
global SERVICE
#Define constants
FILEPATH = os.path.dirname(os.path.realpath(__file__))
SERVICE = 'service.log'
logging.basicConfig(
filename = '%s\\%s' % (FILEPATH, SERVICE),
level = logging.DEBUG,
format = '[Logging Service] %(levelname)-7.7s %(message)s'
)
def hi(text):
logging.info(text)
return
class HelloWorldSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "Logging-Service"
_svc_display_name_ = "Logging Service"
_svc_description_ = "Periodically logs information"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.stop_event = win32event.CreateEvent(None,0,0,None)
socket.setdefaulttimeout(60)
self.stop_requested = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
logging.info('Stopping service ...')
self.stop_requested = True
def SvcDoRun(self):
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
self.main()
def main(self):
logging.info(' ** Starting Logging Operation ** ')
scheduler = BackgroundScheduler()
scheduler.add_job(hi, 'interval', seconds=5, args=['arg text'])
scheduler.start()
time.sleep(15)
scheduler.shutdown()
time.sleep(10)
logging.info('Ended')
return
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(HelloWorldSvc)
Did you try stopping it like this:
win32serviceutil.StopService(service, machine)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With