471,602 Members | 1,238 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,602 software developers and data experts.

Windows XMLRPC Service

Hi,

I'm trying to serve up a simple XMLRPC server as a windows service. I
got it to run properly, I'm just not sure how to stop it properly.
Most of the documentation/examples I found for this was from forums,
so I'd love some links to relevant info also. Here's what I
have...taken from the cookbook with the xmlrpc server added:

import win32serviceutil
import win32service
import win32event

import SimpleXMLRPCServer

class MyClass(object):
def hello(self):
return "Hello World!"

class SmallestPythonService(win32serviceutil.ServiceFram ework):
_svc_name_ = "PythonXMLRPC"
_svc_display_name_ = "PythonXMLRPC"

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
# Create an event which we will use to wait on.
# The "service stop" request will set this event.
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

def SvcStop(self):
# Before we do anything, tell the SCM we are starting the stop
process.
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)

# quit the xmlrpc sever
self.server.quit()

# And set my event.
win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
# Serve up the XMLRPC forever
self.server =
SimpleXMLRPCServer.SimpleXMLRPCServer(("10.0.1.6", 8000))
self.server.register_instance(MyClass())
self.server.serve_forever()

win32event.WaitForSingleObject(self.hWaitStop)
if __name__=='__main__':
win32serviceutil.HandleCommandLine(SmallestPythonS ervice)

~Sean

Jun 18 '07 #1
6 2335
En Mon, 18 Jun 2007 00:25:25 -0300, <ha**********@gmail.comescribió:
I'm trying to serve up a simple XMLRPC server as a windows service. I
got it to run properly, I'm just not sure how to stop it properly.
Most of the documentation/examples I found for this was from forums,
so I'd love some links to relevant info also. Here's what I
have...taken from the cookbook with the xmlrpc server added:

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
# Create an event which we will use to wait on.
# The "service stop" request will set this event.
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

def SvcStop(self):
# Before we do anything, tell the SCM we are starting the stop
process.
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)

# quit the xmlrpc sever
self.server.quit()
What is quit()? As the server may be processing a request I'd move any
finalization code below, after exiting the while loop.
>
# And set my event.
win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
# Serve up the XMLRPC forever
self.server =
SimpleXMLRPCServer.SimpleXMLRPCServer(("10.0.1.6", 8000))
self.server.register_instance(MyClass())
self.server.serve_forever()

win32event.WaitForSingleObject(self.hWaitStop)
The simplest solution is to replace serve_forever with a loop waiting on
hWaitStop:

while WaitForSingleObject(self.hWaitStop, 0)==WAIT_TIMEOUT:
self.server.handle_request()

Set the socket timeout to a reasonable value (you'll have to wait that
time before exiting). Also, a ThreadingTCPServer may be better if you
expect more than a request at a time. If you search past messages you may
find other ways.

--
Gabriel Genellina

Jun 18 '07 #2
On Jun 18, 2:16 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Mon, 18 Jun 2007 00:25:25 -0300, <half.ital...@gmail.comescribió:


I'm trying to serve up a simple XMLRPC server as a windows service. I
got it to run properly, I'm just not sure how to stop it properly.
Most of the documentation/examples I found for this was from forums,
so I'd love some links to relevant info also. Here's what I
have...taken from the cookbook with the xmlrpc server added:
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
# Create an event which we will use to wait on.
# The "service stop" request will set this event.
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
# Before we do anything, tell the SCM we are starting the stop
process.
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)
# quit the xmlrpc sever
self.server.quit()

What is quit()? As the server may be processing a request I'd move any
finalization code below, after exiting the while loop.
# And set my event.
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
# Serve up the XMLRPC forever
self.server =
SimpleXMLRPCServer.SimpleXMLRPCServer(("10.0.1.6", 8000))
self.server.register_instance(MyClass())
self.server.serve_forever()
win32event.WaitForSingleObject(self.hWaitStop)

The simplest solution is to replace serve_forever with a loop waiting on
hWaitStop:

while WaitForSingleObject(self.hWaitStop, 0)==WAIT_TIMEOUT:
self.server.handle_request()

Set the socket timeout to a reasonable value (you'll have to wait that
time before exiting). Also, a ThreadingTCPServer may be better if you
expect more than a request at a time. If you search past messages you may
find other ways.

--
Gabriel Genellina- Hide quoted text -

- Show quoted text -
I can't quite figure out where to set the "socket timeout". I tried
setting win32event.WAIT_TIMEOUT, but I'm pretty sure that's not the
variable you were talking about. I did manage to make it multi-
threaded by incorporating a different recipe, and I'm beginning to
understand the control flow a bit better, but it doesn't seem to be
doing what I expect. When SvcStop() is executed and calls
win32event.SetEvent(self.hWaitStop), the while loop should break as
win32event.WaitForSingleObject(self.hWaitStop, 0) returns zero at this
point. But it doesn't do that. What am I missing?

import win32serviceutil
import win32service
import win32event

import SocketServer
from SimpleXMLRPCServer import
SimpleXMLRPCServer,SimpleXMLRPCRequestHandler

# Threaded mix-in
class
AsyncXMLRPCServer(SocketServer.ThreadingMixIn,Simp leXMLRPCServer):
pass
class MyClass(object):
def hello(self):
return "Hello World"

class SmallestPythonService(win32serviceutil.ServiceFram ework):
_svc_name_ = "PythonXMLRPC"
_svc_display_name_ = "PythonXMLRPC"

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
# Create an event which we will use to wait on.
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
import socket
localhost = socket.gethostbyname(socket.gethostname())
self.server = AsyncXMLRPCServer((localhost, 8000),
SimpleXMLRPCRequestHandler)

def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)
win32event.SetEvent(self.hWaitStop)
#print "EVENT:",
win32event.WaitForSingleObject(self.hWaitStop, 0) # returns 0 here

def SvcDoRun(self):
self.server.register_instance(MyClass())

#win32event.WAIT_TIMEOUT = 2 --- This just makes the loop
never execute because
# the WaitFor... part always returns 258

while win32event.WaitForSingleObject(self.hWaitStop, 0) ==
win32event.WAIT_TIMEOUT:
self.server.handle_request()

if __name__ == '__main__':
win32serviceutil.HandleCommandLine(SmallestPythonS ervice)

Thanks for any help!

~Sean

Jun 19 '07 #3
En Tue, 19 Jun 2007 03:45:19 -0300, <ha**********@gmail.comescribió:

I can't quite figure out where to set the "socket timeout". I tried
setting win32event.WAIT_TIMEOUT, but I'm pretty sure that's not the
variable you were talking about. I did manage to make it multi-
threaded by incorporating a different recipe, and I'm beginning to
understand the control flow a bit better, but it doesn't seem to be
doing what I expect. When SvcStop() is executed and calls
win32event.SetEvent(self.hWaitStop), the while loop should break as
win32event.WaitForSingleObject(self.hWaitStop, 0) returns zero at this
point. But it doesn't do that. What am I missing?
May be because you didn't set correctly the socket timeout. See the
comments below.
>
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)
win32event.SetEvent(self.hWaitStop)
#print "EVENT:",
win32event.WaitForSingleObject(self.hWaitStop, 0) # returns 0 here
That's OK, since you have set the event.
def SvcDoRun(self):
self.server.register_instance(MyClass())

#win32event.WAIT_TIMEOUT = 2 --- This just makes the loop
never execute because
# the WaitFor... part always returns 258
WAIT_TIMEOUT is 258. How do you see it is 2?
For example, see <http://msdn2.microsoft.com/en-us/library/ms681382.aspx>.
Python 2.5.1 + pywin32 210 prints this on my PC:
pyimport win32event
pywin32event.WAIT_TIMEOUT
258
while win32event.WaitForSingleObject(self.hWaitStop, 0) ==
win32event.WAIT_TIMEOUT:
self.server.handle_request()
The loop above should keep running until hWaitStop is set, with a maximum
wait time (inside handle_request) corresponding to the socket timeout
value.
You can either:
- use socket.setdefaulttimeout() (in __init__, by example) before anything
else. This will set a global timeout for all sockets.
- modify the socket instance. Just add this method to your AsyncServer:
def server_activate(self):
SimpleXMLRPCServer.server_activate(self)
self.socket.settimeout(15) # for 15 secs
--
Gabriel Genellina

Jun 19 '07 #4
On Jun 19, 10:21 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Tue, 19 Jun 2007 03:45:19 -0300, <half.ital...@gmail.comescribió:
I can't quite figure out where to set the "socket timeout". I tried
setting win32event.WAIT_TIMEOUT, but I'm pretty sure that's not the
variable you were talking about. I did manage to make it multi-
threaded by incorporating a different recipe, and I'm beginning to
understand the control flow a bit better, but it doesn't seem to be
doing what I expect. When SvcStop() is executed and calls
win32event.SetEvent(self.hWaitStop), the while loop should break as
win32event.WaitForSingleObject(self.hWaitStop, 0) returns zero at this
point. But it doesn't do that. What am I missing?

May be because you didn't set correctly the socket timeout. See the
comments below.
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)
win32event.SetEvent(self.hWaitStop)
#print "EVENT:",
win32event.WaitForSingleObject(self.hWaitStop, 0) # returns 0 here

That's OK, since you have set the event.
def SvcDoRun(self):
self.server.register_instance(MyClass())
#win32event.WAIT_TIMEOUT = 2 --- This just makes the loop
never execute because
# the WaitFor... part always returns 258

WAIT_TIMEOUT is 258. How do you see it is 2?
For example, see <http://msdn2.microsoft.com/en-us/library/ms681382.aspx>.
Python 2.5.1 + pywin32 210 prints this on my PC:
pyimport win32event
pywin32event.WAIT_TIMEOUT
258
while win32event.WaitForSingleObject(self.hWaitStop, 0) ==
win32event.WAIT_TIMEOUT:
self.server.handle_request()

The loop above should keep running until hWaitStop is set, with a maximum
wait time (inside handle_request) corresponding to the socket timeout
value.
You can either:
- use socket.setdefaulttimeout() (in __init__, by example) before anything
else. This will set a global timeout for all sockets.
- modify the socket instance. Just add this method to your AsyncServer:
def server_activate(self):
SimpleXMLRPCServer.server_activate(self)
self.socket.settimeout(15) # for 15 secs

--
Gabriel Genellina
def SvcDoRun(self):
self.server.register_instance(MyClass())
#win32event.WAIT_TIMEOUT = 2 --- This just makes the loop
never execute because
# the WaitFor... part always returns 258

WAIT_TIMEOUT is 258. How do you see it is 2?
For example, see <http://msdn2.microsoft.com/en-us/library/ms681382.aspx>.
Python 2.5.1 + pywin32 210 prints this on my PC:
pyimport win32event
pywin32event.WAIT_TIMEOUT
258
I meant here that *if* I set the WAIT_TIMEOUT to 2, then I see that
behavior.
- use socket.setdefaulttimeout() (in __init__, by example) before anything
else. This will set a global timeout for all sockets.
That was the one that did it.

Thank you again Gabriel. I'll post back with something complete.

~Sean

Jun 19 '07 #5
En Tue, 19 Jun 2007 14:57:10 -0300, <ha**********@gmail.comescribió:
#win32event.WAIT_TIMEOUT = 2 --- This just makes the loop
never execute because
# the WaitFor... part always returns 258

WAIT_TIMEOUT is 258. How do you see it is 2?
pyimport win32event
pywin32event.WAIT_TIMEOUT
258

I meant here that *if* I set the WAIT_TIMEOUT to 2, then I see that
behavior.
Ah, ok! I should have stated clearly that WAIT_TIMEOUT is a Windows
predefined constant, not your desired timeout value.
Thank you again Gabriel. I'll post back with something complete.
Yes, please, a working example would be nice for future readers...

--
Gabriel Genellina

Jun 19 '07 #6
On Jun 19, 12:32 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Tue, 19 Jun 2007 14:57:10 -0300, <half.ital...@gmail.comescribió:
#win32event.WAIT_TIMEOUT = 2 --- This just makes the loop
never execute because
# the WaitFor... part always returns 258
WAIT_TIMEOUT is 258. How do you see it is 2?
pyimport win32event
pywin32event.WAIT_TIMEOUT
258
I meant here that *if* I set the WAIT_TIMEOUT to 2, then I see that
behavior.

Ah, ok! I should have stated clearly that WAIT_TIMEOUT is a Windows
predefined constant, not your desired timeout value.
Thank you again Gabriel. I'll post back with something complete.

Yes, please, a working example would be nice for future readers...

--
Gabriel Genellina
For posterity...

import sys
import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import servicemanager

import SocketServer, socket
from SimpleXMLRPCServer import
SimpleXMLRPCServer,SimpleXMLRPCRequestHandler

# Threaded mix-in
class
AsyncXMLRPCServer(SocketServer.ThreadingMixIn,Simp leXMLRPCServer):
pass

import XMLRPC_funcs # module containing the functions wrapped in a
class

class XMLRPCservice(win32serviceutil.ServiceFramework):
_svc_name_ = "PythonXMLRPC"
_svc_display_name_ = "PythonXMLRPC"
_svc_description_ = "Multi-threaded Python XMLRPC Server"

def __init__(self, args):
# set the timeout so the service can stop...Otherwise it hangs
forever
socket.setdefaulttimeout(15)

win32evtlogutil.AddSourceToRegistry(self._svc_disp lay_name_,
sys.executable, "Application")
win32serviceutil.ServiceFramework.__init__(self, args)

# Create an event which we will use to wait on.
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
localhost = socket.gethostbyname(socket.gethostname())
self.server = AsyncXMLRPCServer((localhost, 8000),
SimpleXMLRPCRequestHandler)

def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP _PENDING)
#send the stop event
win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
# log a start msg

servicemanager.LogMsg(servicemanager.EVENTLOG_INFO RMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ' (%s)' %
self._svc_name_))

self.server.register_instance(XMLRPC_funcs.XMLRPC_ funcs())

# handle requests until the stop event is received
while win32event.WaitForSingleObject(self.hWaitStop, 0) ==
win32event.WAIT_TIMEOUT:
self.server.handle_request()

# log a stopped msg
win32evtlogutil.ReportEvent(self._svc_name_,
servicemanager.PYS_SERVICE_STOPPED,
0,

servicemanager.EVENTLOG_INFORMATION_TYPE,
(self._svc_name_,""))

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

Jun 20 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by glin | last post: by
reply views Thread by Juan Carlos CORUÑA | last post: by
12 posts views Thread by dcrespo | last post: by
reply views Thread by Laszlo Nagy | last post: by
reply views Thread by Rudy Schockaert | last post: by
reply views Thread by Benjamin Grieshaber | last post: by
2 posts views Thread by Guilherme Polo | last post: by
reply views Thread by sarabonn | last post: by
1 post views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by
reply views Thread by CCCYYYY | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.