472,133 Members | 1,079 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

SimpleXMLRPCServer interruptable?

I'm coming back to Python after an absence and it's surprising how
many things I've forgotten since wandering (against my will) into Java
land.

Anyway, I have a need for a way to make SimpleXMLRPCServer
interruptable. Basically, I have a main server that, in response to
certain RPC calls, creates additional servers on different ports. I
then need to be able to shut these additional servers down.

I've got something like this in the __init__ of the class which
contains the spawned servers:

def __init__(self, host, port):
:
:
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while True:
server.handle_request()
except:
pass

One of the methods that I register is:

def shutdown(self):
raise "Quitting time"

Through watching logs and such I can see that the shutdown() method is
getting called, but the loop isn't getting broken. I've done
something like this before in a previous job (so I don't have my
source in front of me, more's the pity) and am hoping someone can
chime in with a good idea.

Thanks in advance!
Bret Wortman
Dec 5 '07 #1
9 3192
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:

def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break

This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....
On Dec 5, 2:00 pm, Bret <bret.wort...@gmail.comwrote:
I'm coming back to Python after an absence and it's surprising how
many things I've forgotten since wandering (against my will) into Java
land.

Anyway, I have a need for a way to make SimpleXMLRPCServer
interruptable. Basically, I have a main server that, in response to
certain RPC calls, creates additional servers on different ports. I
then need to be able to shut these additional servers down.

I've got something like this in the __init__ of the class which
contains the spawned servers:

def __init__(self, host, port):
:
:
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while True:
server.handle_request()
except:
pass

One of the methods that I register is:

def shutdown(self):
raise "Quitting time"

Through watching logs and such I can see that the shutdown() method is
getting called, but the loop isn't getting broken. I've done
something like this before in a previous job (so I don't have my
source in front of me, more's the pity) and am hoping someone can
chime in with a good idea.

Thanks in advance!

Bret Wortman
Dec 5 '07 #2
En Wed, 05 Dec 2007 18:20:35 -0300, Bret <br**********@gmail.comescribió:
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:

def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break

This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....
You could try setting a reasonable timeout on the listening socket; I
would override the server_bind method, calling self.socket.settimeout(xxx)
before calling the inherited method. I've never actually done it with a
SimpleXMLRPCServer, but *should* work. Don't use a very small timeout,
because it affects *all* subsequent operations.

--
Gabriel Genellina

Dec 6 '07 #3
On Dec 5, 6:22 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.arwrote:
En Wed, 05 Dec 2007 18:20:35 -0300, Bret <bret.wort...@gmail.comescribió:
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:
def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break
This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....

You could try setting a reasonable timeout on the listening socket; I
would override the server_bind method, calling self.socket.settimeout(xxx)
before calling the inherited method. I've never actually done it with a
SimpleXMLRPCServer, but *should* work. Don't use a very small timeout,
because it affects *all* subsequent operations.

--
Gabriel Genellina
Try this:

def __init__(self, host, port):
self.done = False
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while not self.done:
server.handle_request()
except:
pass

Your shutdown method becomes:

def shutdown(self):
self.done = True

HTH

-Edward Kozlowski
Dec 6 '07 #4
On Dec 5, 10:19 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 6:22 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.arwrote:
En Wed, 05 Dec 2007 18:20:35 -0300, Bret <bret.wort...@gmail.comescribió:
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:
def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break
This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....
You could try setting a reasonable timeout on the listening socket; I
would override the server_bind method, calling self.socket.settimeout(xxx)
before calling the inherited method. I've never actually done it with a
SimpleXMLRPCServer, but *should* work. Don't use a very small timeout,
because it affects *all* subsequent operations.
--
Gabriel Genellina

Try this:

def __init__(self, host, port):
self.done = False
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while not self.done:
server.handle_request()
except:
pass

Your shutdown method becomes:

def shutdown(self):
self.done = True

HTH

-Edward Kozlowski
Sorry about the first post, I shot from the hip and had to make a few
more modifications to make it 'working' code. The example below works
fine for me.

import SimpleXMLRPCServer

class myServer:
def __init__(self, host, port):
self.done = False
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer((host,
port))

def shutdown(self):
self.done = True
return 0

def getName(self):
return "Hey, I'm Ed"

def serverWrapper(self):
self.server.register_function(self.getName)
self.server.register_function(self.shutdown)
try:
while not self.done:
self.server.handle_request()
except:
pass
if __name__ == "__main__":
myServer('localhost', 6058).serverWrapper()

----
>>s.getName()
"Hey, I'm Ed"
>>s.shutdown()
0

Dec 6 '07 #5
On Dec 5, 10:00 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 10:19 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 6:22 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.arwrote:
En Wed, 05 Dec 2007 18:20:35 -0300, Bret <bret.wort...@gmail.comescribió:
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:
def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break
This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....
You could try setting a reasonable timeout on the listening socket; I
would override the server_bind method, calling self.socket.settimeout(xxx)
before calling the inherited method. I've never actually done it with a
SimpleXMLRPCServer, but *should* work. Don't use a very small timeout,
because it affects *all* subsequent operations.
--
Gabriel Genellina
Try this:
def __init__(self, host, port):
self.done = False
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while not self.done:
server.handle_request()
except:
pass
Your shutdown method becomes:
def shutdown(self):
self.done = True
HTH
-Edward Kozlowski

Sorry about the first post, I shot from the hip and had to make a few
more modifications to make it 'working' code. The example below works
fine for me.

import SimpleXMLRPCServer

class myServer:
def __init__(self, host, port):
self.done = False
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer((host,
port))

def shutdown(self):
self.done = True
return 0

def getName(self):
return "Hey, I'm Ed"

def serverWrapper(self):
self.server.register_function(self.getName)
self.server.register_function(self.shutdown)
try:
while not self.done:
self.server.handle_request()
except:
pass

if __name__ == "__main__":
myServer('localhost', 6058).serverWrapper()

---->>s.getName()
"Hey, I'm Ed"
>s.shutdown()

0
Thanks to all! I'm now keeping a file of my own snippets in hardcopy
so I won't lose them next time I change jobs. :-)
Bret
Dec 6 '07 #6
On Dec 6, 7:04 am, Bret <bret.wort...@gmail.comwrote:
On Dec 5, 10:00 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 10:19 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 6:22 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.arwrote:
En Wed, 05 Dec 2007 18:20:35 -0300, Bret <bret.wort...@gmail.comescribió:
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:
def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break
This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....
You could try setting a reasonable timeout on the listening socket; I
would override the server_bind method, calling self.socket.settimeout(xxx)
before calling the inherited method. I've never actually done it with a
SimpleXMLRPCServer, but *should* work. Don't use a very small timeout,
because it affects *all* subsequent operations.
--
Gabriel Genellina
Try this:
def __init__(self, host, port):
self.done = False
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while not self.done:
server.handle_request()
except:
pass
Your shutdown method becomes:
def shutdown(self):
self.done = True
HTH
-Edward Kozlowski
Sorry about the first post, I shot from the hip and had to make a few
more modifications to make it 'working' code. The example below works
fine for me.
import SimpleXMLRPCServer
class myServer:
def __init__(self, host, port):
self.done = False
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer((host,
port))
def shutdown(self):
self.done = True
return 0
def getName(self):
return "Hey, I'm Ed"
def serverWrapper(self):
self.server.register_function(self.getName)
self.server.register_function(self.shutdown)
try:
while not self.done:
self.server.handle_request()
except:
pass
if __name__ == "__main__":
myServer('localhost', 6058).serverWrapper()
---->>s.getName()
"Hey, I'm Ed"
>>s.shutdown()
0

Thanks to all! I'm now keeping a file of my own snippets in hardcopy
so I won't lose them next time I change jobs. :-)

Bret
Oops, this actually misses part of the problem -- I need to construct
this server programmatically, so imbedding the call to start the
server in the "if __name__" construct doesn't work. If I start it
within the __init__, then the object that's creating it gets stuck
waiting for it to finish, which it never will. I need this to be
autonomous, which is why I was trying to do the start of the server in
a separate thread, but that doesn't seem to work either (that's what's
causing my process to need the second call; the thread completes the
loop and enters the next handle_request() call before the event or
boolean gets set).

Basically, I need a way for one server to start other autonomous
servers without waiting on them, and still retain the ability to shut
them down when their work is done.

Back to the keyboard. ;-)
Bret
Dec 6 '07 #7
On Dec 6, 7:04 am, Bret <bret.wort...@gmail.comwrote:
On Dec 5, 10:00 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 10:19 pm, Edward Kozlowski <ekozlows...@gmail.comwrote:
On Dec 5, 6:22 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.arwrote:
En Wed, 05 Dec 2007 18:20:35 -0300, Bret <bret.wort...@gmail.comescribió:
I just tried changing this so that I now have a threading.Event()
called self.done, which is set within the body of the shutdown()
method. The serverWrapper loop now looks like this:
def serverWrapper():
while True:
server.handle_request()
if self.done.isSet():
break
This works, but only if I follow the shutdown() rpc call a few seconds
later with ... something else to cause handle_request() to complete
again. Obviously, not quite the right approach....
You could try setting a reasonable timeout on the listening socket; I
would override the server_bind method, calling self.socket.settimeout(xxx)
before calling the inherited method. I've never actually done it with a
SimpleXMLRPCServer, but *should* work. Don't use a very small timeout,
because it affects *all* subsequent operations.
--
Gabriel Genellina
Try this:
def __init__(self, host, port):
self.done = False
server = SimpleXMLRPCServer((host, port))
:
: Bunch of server.register_function calls
:
def serverWrapper():
try:
while not self.done:
server.handle_request()
except:
pass
Your shutdown method becomes:
def shutdown(self):
self.done = True
HTH
-Edward Kozlowski
Sorry about the first post, I shot from the hip and had to make a few
more modifications to make it 'working' code. The example below works
fine for me.
import SimpleXMLRPCServer
class myServer:
def __init__(self, host, port):
self.done = False
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer((host,
port))
def shutdown(self):
self.done = True
return 0
def getName(self):
return "Hey, I'm Ed"
def serverWrapper(self):
self.server.register_function(self.getName)
self.server.register_function(self.shutdown)
try:
while not self.done:
self.server.handle_request()
except:
pass
if __name__ == "__main__":
myServer('localhost', 6058).serverWrapper()
---->>s.getName()
"Hey, I'm Ed"
>>s.shutdown()
0

Thanks to all! I'm now keeping a file of my own snippets in hardcopy
so I won't lose them next time I change jobs. :-)

Bret
For completeness, what I ended up doing is this:

server = SimpleXMLRPCServer((host, port))
server.socket.settimeout(0.1)

ServerWrapper became:

def ServerWrapper():
while True:
try:
server.handle_request()
if self.done.isSet():
break
except timeout:
pass

And that seems to do the trick! Giving the socket a timeout allows me
to check the Event more frequently and catch the change within a
reasonable time.

Thanks again, Ed and Gabriel.
Bret
Dec 6 '07 #8
En Thu, 06 Dec 2007 13:11:09 -0300, Bret <br**********@gmail.comescribió:
For completeness, what I ended up doing is this:

server = SimpleXMLRPCServer((host, port))
server.socket.settimeout(0.1)

ServerWrapper became:

def ServerWrapper():
while True:
try:
server.handle_request()
if self.done.isSet():
break
except timeout:
pass

And that seems to do the trick! Giving the socket a timeout allows me
to check the Event more frequently and catch the change within a
reasonable time.
Remember that the timeout applies to *all* socket operations; what if the
XML request requires more than 0.1s to read?
If handling large requests is more important than the delay at shutdown
time, consider raising that value.

--
Gabriel Genellina

Dec 7 '07 #9
On Dec 6, 7:43 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.arwrote:
En Thu, 06 Dec 2007 13:11:09 -0300, Bret <bret.wort...@gmail.comescribió:
For completeness, what I ended up doing is this:
server = SimpleXMLRPCServer((host, port))
server.socket.settimeout(0.1)
ServerWrapper became:
def ServerWrapper():
while True:
try:
server.handle_request()
if self.done.isSet():
break
except timeout:
pass
And that seems to do the trick! Giving the socket a timeout allows me
to check the Event more frequently and catch the change within a
reasonable time.

Remember that the timeout applies to *all* socket operations; what if the
XML request requires more than 0.1s to read?
If handling large requests is more important than the delay at shutdown
time, consider raising that value.

--
Gabriel Genellina
Good point. Thanks!
Dec 10 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Marco Aschwanden | last post: by
3 posts views Thread by Maxim Khesin | last post: by
4 posts views Thread by codecraig | last post: by
reply views Thread by Thomas G. Apostolou | last post: by
2 posts views Thread by Laszlo Nagy | last post: by
reply views Thread by Jeremy Monnet | last post: by
reply views Thread by Juju | last post: by
3 posts views Thread by Achim Domma | 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.