[Twisted-Python] twisted as windows service
John Aherne
johnaherne at rocs.co.uk
Tue Oct 11 05:10:09 MDT 2011
I have been looking for some info on running twisted as a Windows Service.
I have found various examples in mailing-lists and blogs that vary in what
seem to be important respects.
I have included them below as 3 examples.
The problem I have is working out which scheme or combination I should be
adopting.
I have tried out some of the options and they appear to work. But I need
something better than seems to work.
My gut reaction is that I should be putting all my imports into SvcDoRun,
since they will be used in the thread.
But if I import the reactor in SvcDoRun, should I be
using reactor.callfromthread(reactor.stop). I think not
I think the use of waitforobject is the right thing to do as well without
fully understanding it at the moment.
If anyone can throw some light on what to do I shall be very grateful.
It could be that I should post this question to python-windows mailing
list since it seems to me more pertinent to windows than twisted.
Thanks for any info.
John Aherne
Here is 1st example.
The reactor is imported globally not in SvcDoRun
It uses the waitforobject to detect stopping the service
The reactor.stop is calledfromthread
[Twisted-Python] How to run Twisted as a service in Windows?
Thomas Jacob jacob at internet24.de
Wed Aug 9 10:49:30 EDT 2006
Previous message: [Twisted-Python] How to run Twisted as a service in
Windows?
Next message: [Twisted-Python] How to run Twisted as a service in Windows?
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
AFAIK, twistd doesn't provide direct support for Windows Services yet
(Is this planned?).
But you can easily wrap a reactor,run() yourself by doing something
like the following using the Win32-Python packages
import win32serviceutil
import win32service
import win32event
from twisted.internet import reactor
import sys
class IMSAgentBase(win32serviceutil.ServiceFramework):
_svc_name_ = "myService"
_svc_display_name_ = "My little Service"
_svc_description_ = "My little Service" # Win2k or later
_svc_deps_ = ["RpcSs"] # Start after the Network has come up...
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)
reactor.callFromThread(reactor.stop)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
# initialize your services here
reactor.run()
win32event.WaitForSingleObject(self.hWaitStop,win32event.INFINITE)
def HandleCommandLine(cls):
win32serviceutil.HandleCommandLine(cls)
Run the above as a script.
Here is the 2nd example.
The imports are global not in SvcDoRun
And the reactor .stop is not called from thread.
And the wait for stop event is in a timeout loop
It uses waitforobject events
It sets installsignalhandlers to 0
You can then test it out with the sample Echo client from the core docs.
"""qotdservice.py
Sample Twisted Windows Service
"""
# Service Utilities
import win32serviceutil
import win32service
import win32event
# Twisted imports
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
class QOTD(Protocol):
def connectionMade(self):
self.transport.write("An apple a day keeps the doctor away\r\n")
self.transport.loseConnection()
class WindowsService(win32serviceutil.ServiceFramework):
_svc_name_ = "TwistedWin32Service"
_svc_display_name_ = "Twisted Win32 Service"
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):
import servicemanager
self.CheckForQuit()
factory = Factory()
factory.protocol = QOTD
reactor.listenTCP(8007, factory)
reactor.run(installSignalHandlers=0)
def CheckForQuit(self):
retval = win32event.WaitForSingleObject(self.hWaitStop, 10)
if not retval == win32event.WAIT_TIMEOUT:
# Received Quit from Win32
reactor.stop()
reactor.callLater(1.0, self.CheckForQuit)
if __name__=='__main__':
win32serviceutil.HandleCommandLine(WindowsService)
Here is the 3rd example.
The imports are done in SvcDoRun.
There is no callfrom thread
It does not use the waitforobject
import sys, os
import win32serviceutil, win32service
class MyService(win32serviceutil.ServiceFramework):
"""NT Service."""
_svc_name_ = "MyService"
_svc_display_name_ = "MyService server"
def SvcDoRun(self):
import server
f = open(os.path.join(server.rootPath, "cyberhigh.log"), 'a')
from twisted.python.log import startLogging
from twisted.application.app import startApplication
from twisted.internet import reactor
startLogging(f)
startApplication(server.application, 0)
reactor.run()
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
from twisted.internet import reactor
reactor.stop()
if __name__ == '__main__':</pre>
win32serviceutil.HandleCommandLine(MyService)</pre>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20111011/7eb72b38/attachment.html>
More information about the Twisted-Python
mailing list