Skip to content

Instantly share code, notes, and snippets.

@tiagocoutinho
Last active January 28, 2018 08:51
Show Gist options
  • Save tiagocoutinho/edea201e95635021022a09579b17cfae to your computer and use it in GitHub Desktop.
Save tiagocoutinho/edea201e95635021022a09579b17cfae to your computer and use it in GitHub Desktop.
Safe XML RPC calls in multiple gevent tasks
"""
Safe XML RPC calls in multiple gevent tasks. Basically, it serializes calls.
Assuming you are running a server like this::
import time
from SimpleXMLRPCServer import SimpleXMLRPCServer
def is_even(n):
time.sleep(3)
return n % 2 == 0
server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(is_even, "toto.is_even")
server.serve_forever()
Usage::
# You need to monkey patch to force xmlrpclib to use gevent socket
from gevent.monkey import patch_all
patch_all(thread=False)
from xmlrpclib_gevent import ServerProxy
proxy = ServerProxy('http://localhost:8000')
def is_even(proxy, number):
result = proxy.toto.is_even(number)
print('Is {0} even? {1}'.format(number, result))
task1 = gevent.spawn(is_even, proxy, 55)
task2 = gevent.spawn(is_even, proxy, 44)
gevent.joinall((task1, task2))
"""
from xmlrpclib import ServerProxy as _ServerProxy
from gevent.lock import RLock
class Wrap(object):
def __init__(self, lock, method):
self.__lock = lock
self.__method = method
def __getattr__(self, name):
return Wrap(self.__lock, getattr(self.__method, name))
def __call__(self, *args):
with self.__lock:
return self.__method(*args)
class ServerProxy(_ServerProxy):
def __init__(self, *args, **kwargs):
self.__lock = RLock()
_ServerProxy.__init__(self, *args, **kwargs)
def __getattr__(self, name):
method = _ServerProxy.__getattr__(self, name)
return Wrap(self.__lock, method)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment