From 45394c281d09de67e16be0d56ff04ddb5b6f6011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Fri, 31 Oct 2003 13:49:36 +0000 Subject: Patch #531629: Add multicall support. --- Doc/lib/libxmlrpclib.tex | 29 +++++++++++++++++++++ Lib/xmlrpclib.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++- Misc/NEWS | 2 ++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/Doc/lib/libxmlrpclib.tex b/Doc/lib/libxmlrpclib.tex index f420f25..a285c16 100644 --- a/Doc/lib/libxmlrpclib.tex +++ b/Doc/lib/libxmlrpclib.tex @@ -252,6 +252,35 @@ A string containing the headers of the HTTP/HTTPS request that triggered the error. \end{memberdesc} +\subsection{MultiCall Objects} + +\versionadded{2.4} + +In \url{http://www.xmlrpc.com/discuss/msgReader\$1208}, an approach +is presented to encapsulate multiple calls to a remote server into +a single request. + +\begin{classdesc}{MultiCall}{server} + +Create an object used to boxcar method calls. \var{server} is the +eventual target of the call. Calls can be made to the result object, +but they will immediately return \var{None}, and only store the +call name and parameters in the \class{MultiCall} object. Calling +the object itself causes all stored calls to be transmitted as +a single \code{system.multicall} request. The result of this call +is a generator; iterating over this generator yields the individual +results. + +\end{classdesc} + +A usage example of this class is + +\begin{verbatim} +multicall = MultiCall(server_proxy) +multicall.add(2,3) +multicall.get_address("Guido") +add_result, address = multicall() +\end{verbatim} \subsection{Convenience Functions} diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py index 20d6e71..f06cfd7 100644 --- a/Lib/xmlrpclib.py +++ b/Lib/xmlrpclib.py @@ -50,6 +50,7 @@ # 2003-04-25 ak Add support for nil # 2003-06-15 gn Add support for time.struct_time # 2003-07-12 gp Correct marshalling of Faults +# 2003-10-31 mvl Add multicall support # # Copyright (c) 1999-2002 by Secret Labs AB. # Copyright (c) 1999-2002 by Fredrik Lundh. @@ -108,6 +109,7 @@ Exported classes: ServerProxy Represents a logical connection to an XML-RPC server + MultiCall Executor of boxcared xmlrpc requests Boolean boolean wrapper to generate a "boolean" XML-RPC value DateTime dateTime wrapper for an ISO 8601 string or time tuple or localtime integer value to generate a "dateTime.iso8601" @@ -875,7 +877,69 @@ class Unmarshaller: self._type = "methodName" # no params dispatch["methodName"] = end_methodName +## Multicall support +# + +class _MultiCallMethod: + # some lesser magic to store calls made to a MultiCall object + # for batch execution + def __init__(self, call_list, name): + self.__call_list = call_list + self.__name = name + def __getattr__(self, name): + return _MultiCallMethod(self.__call_list, "%s.%s" % (self.__name, name)) + def __call__(self, *args): + self.__call_list.append((self.__name, args)) + +def MultiCallIterator(results): + """Iterates over the results of a multicall. Exceptions are + thrown in response to xmlrpc faults.""" + + for i in results: + if type(i) == type({}): + raise Fault(i['faultCode'], i['faultString']) + elif type(i) == type([]): + yield i[0] + else: + raise ValueError,\ + "unexpected type in multicall result" + +class MultiCall: + """server -> a object used to boxcar method calls + + server should be a ServerProxy object. + + Methods can be added to the MultiCall using normal + method call syntax e.g.: + + multicall = MultiCall(server_proxy) + multicall.add(2,3) + multicall.get_address("Guido") + To execute the multicall, call the MultiCall object e.g.: + + add_result, address = multicall() + """ + + def __init__(self, server): + self.__server = server + self.__call_list = [] + + def __repr__(self): + return "" % id(self) + + __str__ = __repr__ + + def __getattr__(self, name): + return _MultiCallMethod(self.__call_list, name) + + def __call__(self): + marshalled_list = [] + for name, args in self.__call_list: + marshalled_list.append({'methodName' : name, 'params' : args}) + + return MultiCallIterator(self.__server.system.multicall(marshalled_list)) + # -------------------------------------------------------------------- # convenience functions @@ -1328,7 +1392,7 @@ class ServerProxy: ) __str__ = __repr__ - + def __getattr__(self, name): # magic method dispatcher return _Method(self.__request, name) diff --git a/Misc/NEWS b/Misc/NEWS index 970c814..2449dec 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -101,6 +101,8 @@ Extension modules Library ------- +- xmlrpclib.MultiCall has been added. + - poplib.POP3_SSL has been added. - tmpfile.mkstemp now returns an absolute path even if dir is relative. -- cgit v0.12