summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2003-10-31 13:49:36 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2003-10-31 13:49:36 (GMT)
commit45394c281d09de67e16be0d56ff04ddb5b6f6011 (patch)
tree15f9733b6837457db4d325cade56d84abd254937
parentf9b08b8e609916f970dc5ba2e41c9dbe1897240a (diff)
downloadcpython-45394c281d09de67e16be0d56ff04ddb5b6f6011.zip
cpython-45394c281d09de67e16be0d56ff04ddb5b6f6011.tar.gz
cpython-45394c281d09de67e16be0d56ff04ddb5b6f6011.tar.bz2
Patch #531629: Add multicall support.
-rw-r--r--Doc/lib/libxmlrpclib.tex29
-rw-r--r--Lib/xmlrpclib.py66
-rw-r--r--Misc/NEWS2
3 files changed, 96 insertions, 1 deletions
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 "<MultiCall at %x>" % 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.