William Troup
William Troup

Reputation: 13131

python service restart (when compiled to exe)

I have a service, as follows:

"""
The most basic (working) CherryPy 3.1 Windows service possible.
Requires Mark Hammond's pywin32 package.
"""

import cherrypy
import win32serviceutil
import win32service
import sys
import __builtin__

__builtin__.theService = None

class HelloWorld:
    """ Sample request handler class. """

    def __init__(self):
        self.iVal = 0

    @cherrypy.expose
    def index(self):

        try:

            self.iVal += 1 

            if self.iVal == 5:
                sys.exit()
            return "Hello world! " + str(self.iVal) 

        except SystemExit:
            StopServiceError(__builtin__.theService)


class MyService(win32serviceutil.ServiceFramework):
    """NT Service."""

    _svc_name_ = "CherryPyService"
    _svc_display_name_ = "CherryPy Service"
    _svc_description_ = "Some description for this service"

    def SvcDoRun(self):
        __builtin__.theService = self
        StartService()


    def SvcStop(self):
        StopService(__builtin__.theService)


def StartService():

    cherrypy.tree.mount(HelloWorld(), '/')

    cherrypy.config.update({
        'global':{
            'tools.log_tracebacks.on': True,
            'log.error_file': '\\Error_File.txt',
            'log.screen': True,
            'engine.autoreload.on': False,
            'engine.SIGHUP': None,
            'engine.SIGTERM': None
            }
        })

    cherrypy.engine.start()
    cherrypy.engine.block()


def StopService(classObject):
    classObject.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    cherrypy.engine.exit()
    classObject.ReportServiceStatus(win32service.SERVICE_STOPPED)


def StopServiceError(classObject):
    classObject.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    cherrypy.engine.exit()
    classObject.ReportServiceStatus(serviceStatus=win32service.SERVICE_STOPPED, win32ExitCode=1, svcExitCode=1)

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(MyService)

I want windows to restart the service when the sys.ext() cause the service to exit. Does anyone know how to make it do this?

Upvotes: 1

Views: 2754

Answers (2)

narthi
narthi

Reputation: 2228

I've had exactly the same issue: trying to make a Python-based service exit with an error code so that the services framework can restart it. I tried the approach with ReportServiceStatus(win32service.SERVICE_STOP_PENDING, win32ExitCode=1, svcExitCode=1) as well as sys.exit(1) but none of them prompted Windows to restart the service, despite the latter showing up as an error in the event log. I ended up not relying on the services framework and just doing this:

def SvcDoRun(self):
    restart_required = run_service() # will return True if the service needs
                                     # to be restarted
    if restart_required:
        subprocess.Popen('sleep 5 & sc start %s' % self._svc_name_, shell=True)

Upvotes: 2

gimel
gimel

Reputation: 86472

A non programming-related option:

A windows service can be configured for recovery. Select the recovery tag of the service properties window. You can select to Restart the Service after the first, second or subsequent failures.

A simple idea - why don't you drop the sys.exit() call? This way the service just continues to run and you don't have to deal with restarting it. If you really need to know when self.iVal reaches 5, you can report to the event logger (and perhaps reset the counter).

Upvotes: 4

Related Questions