Last active
January 28, 2018 08:51
-
-
Save tiagocoutinho/edea201e95635021022a09579b17cfae to your computer and use it in GitHub Desktop.
Safe XML RPC calls in multiple gevent tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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