I have a flask/gevent SocketIOServer and need to make it work as a service:
class TeleportService(win32serviceutil.ServiceFramework):
_svc_name_ = "TeleportServer"
_svc_display_name_ = "Teleport Database Backup Service"
_svc_description_ = "More info at www.elmalabarista.com/teleport"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
runServer()
@werkzeug.serving.run_with_reloader
def runServer():
print 'Listening on %s...' % WEB_PORT
ws = SocketIOServer(('0.0.0.0', WEB_PORT),
SharedDataMiddleware(app, {}),
resource="socket.io",
policy_server=False)
gevent.spawn(runTaskManager).link_exception(lambda *args: sys.exit("important_greenlet died"))
ws.serve_forever()
However, I can't figure how stop it from SvcStop, and running it have the weird behaviour that the service parsing of command line parameters happend AFTER the runserver is killed. This mean the flask server run, I can acces from the web browser but the Service Manager listed it as "Not Started". For example, running in the command line:
C:\Proyectos\TeleportServer>python service.py uninstall <--BAD PARAM, TO MAKE IT OBVIOUS
2013-02-13 16:19:30,786 - DEBUG: Connecting to localhost:9097
* Restarting with reloader
2013-02-13 16:19:32,650 - DEBUG: Connecting to localhost:9097
Listening on 5000...
Growl not available: Teleport Backup Server is started
KeyboardInterrupt <--- HERE I INTERRUPT WITH CTRL-C
Unknown command - 'uninstall'
Usage: 'service.py [options] install|update|remove|start [...]|stop|restart [...
]|debug [...]'
Options for 'install' and 'update' commands only:
--username domain\username : The Username the service is to run under
--password password : The password for the username
--startup [manual|auto|disabled] : How the service starts, default = manual
--interactive : Allow the service to interact with the desktop.
--perfmonini file: .ini file to use for registering performance monitor data
With the suggestion of remove the live reloader, this is the code left. Still, same problem
def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
#self.timeout = 640000 #640 seconds / 10 minutes (value is in milliseconds)
self.timeout = 6000 #120 seconds / 2 minutes
# This is how long the service will wait to run / refresh itself (see script below)
notify.debug("Starting service")
ws = getServer()
while 1:
# Wait for service stop signal, if I timeout, loop again
gevent.sleep(0)
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
# Stop signal encountered
notify.debug("Stopping service")
ws.kill()
servicemanager.LogInfoMsg("TeleportService - STOPPED!") #For Event Log
break
else:
notify.debug("Starting web server")
ws.serve_forever()