Your IP : 172.28.240.42


Current Path : /usr/lib/python2.7/dist-packages/landscape/lib/
Upload File :
Current File : //usr/lib/python2.7/dist-packages/landscape/lib/amp.pyc


Tc@sdZddlmZddlmZmZmZddlmZm	Z	ddl
mZddlm
Z
mZmZmZmZmZmZddlmZmZmZde
fd	YZd
efdYZdefd
YZdefdYZdefdYZdefdYZdefdYZ defdYZ!defdYZ"defdYZ#de	fdYZ$dS(s>Expose the methods of a remote object over AMP.

This module implements an AMP-based protocol for performing remote procedure
calls in a convenient and easy way. It's conceptually similar to DBus in that
it supports exposing a Python object to a remote process, with communication
happening over any Twisted-supported transport, e.g. Unix domain sockets.

For example let's say we have a Python process "A" that creates an instance of
this class::

    class Greeter(object):

        def hello(self, name):
            return "hi %s!" % name

    greeter = Greeter()

Process A can "publish" the greeter object by defining which methods are
exposed remotely and opening a Unix socket for incoming connections::

    factory = MethodCallServerFactory(greeter, ["hello"])
    reactor.listenUNIX("/some/socket/path", factory)

Then a second Python process "B" can connect to that socket and build a
"remote" greeter object, i.e. a proxy that forwards method calls to the
real greeter object living in process A::

    factory = MethodCallClientFactory()
    reactor.connectUNIX("/some/socket/path", factory)

    def got_remote(remote_greeter):
        deferred = remote_greeter.hello("Ted")
        deferred.addCallback(lambda result: ... # result == "hi Ted!")

    factory.getRemoteObject().addCallback(got_remote)

Note that when invoking a method via the remote proxy, the parameters
are required to be serializable with bpickle, so they can be sent over
the wire.

See also::

    http://twistedmatrix.com/documents/current/core/howto/amp.html

for more details about the Twisted AMP protocol.
i(tuuid4(tDeferredt
maybeDeferredtsucceed(t
ServerFactorytReconnectingClientFactory(tFailure(tArgumenttStringtIntegertCommandtAMPtMAX_VALUE_LENGTHtCommandLocator(tloadstdumpstdumps_tabletMethodCallArgumentcBs/eZdZdZdZedZRS(sA bpickle-compatible argument.cCs
t|S(sSerialize an argument.(R(tselftinObject((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyttoString>scCs
t|S(sUnserialize an argument.(R(RtinString((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt
fromStringBscCst|tkS(s%Check if an argument is serializable.(ttypeR(tclsR((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytcheckFs(t__name__t
__module__t__doc__RRtclassmethodR(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR;s		tMethodCallErrorcBseZdZRS(s*Raised when a L{MethodCall} command fails.(RRR(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRLst
MethodCallcBsWeZdZdefdefdefgZdefgZide6Z	RS(sCall a method on the object exposed by a L{MethodCallServerFactory}.

    The command arguments have the following semantics:

    - C{sequence}: An integer uniquely indentifying a the L{MethodCall}
      being issued. The name 'sequence' is a bit misleading because it's
      really a uuid, since its values in practice are not in sequential
      order, they are just random values. The name is kept just for backward
      compatibility.

    - C{method}: The name of the method to invoke on the remote object.

    - C{arguments}: A BPickled binary tuple of the form C{(args, kwargs)},
      where C{args} are the positional arguments to be passed to the method
      and C{kwargs} the keyword ones.
    tsequencetmethodt	argumentstresulttMETHOD_CALL_ERROR(
RRRR	RR"RtresponseRterrors(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRPstMethodCallChunkcBsKeZdZdefdefgZdefgZide6ZRS(sSend a chunk of L{MethodCall} containing a portion of the arguments.

    When a the arguments of a L{MethodCall} are bigger than 64k, they get split
    in several L{MethodCallChunk}s that are buffered on the receiver side.

    The command arguments have the following semantics:

    - C{sequence}: The unique integer associated with the L{MethodCall} that
      this L{MethodCallChunk} is part of.

    - C{chunk}: A portion of the big BPickle C{arguments} string which is
      being split and buffered.
    R tchunkR#R$(	RRRR	RR"R%RR&(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR'ks

tMethodCallReceivercBsDeZdZdZejdZejdZdZ	RS(sExpose methods of a local object over AMP.

    @param obj: The Python object to be exposed.
    @param methods: The list of the object's methods that can be called
         remotely.
    cCs,tj|||_||_i|_dS(N(R
t__init__t_objectt_methodst_pending_chunks(Rtobjtmethods((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*s
		csjj|d}|dk	r@|j|dj|}nt|\}}|jkrttd|ntj	|}fd}d}	t
|||}
|
j||
j|	|
S(sCall an object's method with the given arguments.

        If a connected client sends a L{MethodCall} for method C{foo_bar}, then
        the actual method C{foo_bar} of the object associated with the protocol
        will be called with the given C{args} and C{kwargs} and its return
        value delivered back to the client as response to the command.

        @param sequence: The integer that uniquely identifies the L{MethodCall}
            being received.
        @param method: The name of the object's method to call.
        @param arguments: A bpickle'd binary tuple of (args, kwargs) to be
           passed to the method. In case this L{MethodCall} has been preceded
           by one or more L{MethodCallChunk}s, C{arguments} is the last chunk
           of data.
        tsForbidden method '%s'csij|d6S(NR#(t
_check_result(R#(R(s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt
handle_resultscSst|jdS(N(Rtvalue(tfailure((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pythandle_failuresN(
R-tpoptNonetappendtjoinRR,RtgetattrR+RtaddCallbackt
addErrback(RR R!R"tchunkstargstkwargstmethod_funcR2R5tdeferred((Rs5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytreceive_method_calls
	

cCs'|jj|gj|i|d6S(sReceive a part of a multi-chunk L{MethodCall}.

        Add the received C{chunk} to the buffer of the L{MethodCall} identified
        by C{sequence}.
        R#(R-t
setdefaultR8(RR R(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytreceive_method_call_chunkscCs"tj|stdn|S(sCheck that the C{result} we're about to return is serializable.

        @return: The C{result} itself if valid.
        @raises: L{MethodCallError} if C{result} is not serializable.
        sNon-serializable result(RRR(RR#((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR1s(
RRRR*Rt	responderRBR'RDR1(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR)s
	)
tMethodCallSendercBs;eZdZdZeZdZdZgidZRS(sCall methods on a remote object over L{AMP} and return the result.

    @param protocol: A connected C{AMP} protocol.
    @param clock: An object implementing the C{IReactorTime} interface.

    @ivar timeout: A timeout for remote method class, see L{send_method_call}.
    i<cCs||_||_dS(N(t	_protocolt_clock(Rtprotocoltclock((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*s	cshtfd}fd}|jj|j||jj||}|j|S(sSend an L{AMP} command that will errback in case of a timeout.

        @return: A deferred resulting in the command's response (or failure) if
            the peer responds within C{self.timeout} seconds, or that errbacks
            with a L{MethodCallError} otherwise.
        cs+jsdSjj|dS(N(tactivetcanceltcallback(R%(RAtcall(s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pythandle_responses
csjtddS(Nttimeout(terrbackR((RA(s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pythandle_timeouts(RRHt	callLaterRPRGt
callRemotetaddBoth(RtcommandR?RORRR#((RARNs5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt_call_remote_with_timeouts	
c
st||f}tjgtdt|jD]}|||j!^q:t}tdkrx:d D]+}fd}|j||qWnfd}	|j|	|jd|jd|S(sSend a L{MethodCall} command with the given arguments.

        If a response from the server is not received within C{self.timeout}
        seconds, the returned deferred will errback with a L{MethodCallError}.

        @param method: The name of the remote method to invoke.
        @param args: The positional arguments to pass to the remote method.
        @param kwargs: The keyword arguments to pass to the remote method.

        @return: A C{Deferred} firing with the return value of the method
            invoked on the remote object. If the remote method itself returns
            a deferred, we fire with the callback value of such deferred.
        iiicsfd}|S(NcsjjtddS(NR R((RGRTR'(tx(RR R((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt<lambda>s	((R R(t
send_chunk(R(R(R s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytcreate_send_chunkscs)d}jtddd|S(NiR R!R"(RWR(tignoredR((R R!R=R(s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytsend_last_chunks
cSs|dS(NR#((R%((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRY sN(
RRtinttxrangetlent_chunk_sizeRR;RMR7(
RR!R>R?R"tiR#R(R[R]((R RR=R!s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytsend_method_calls9	

(	RRRRPRRaR*RWRc(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRFs		tMethodCallServerProtocolcBseZdZdZRS(sCReceive L{MethodCall} commands over the wire and send back results.cCs tj|dt||dS(Ntlocator(RR*R)(RR.R/((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*(s(RRRR*(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRd%stMethodCallClientProtocolcBseZdZdZdZRS(sASend L{MethodCall} commands over the wire using the AMP protocol.cCs&|jdk	r"|jj|ndS(s*Notify our factory that we're ready to go.N(tfactoryR7tclientConnectionMade(R((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytconnectionMade1sN(RRRR7RgRi(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRf,stRemoteObjectcBsVeZdZdZdZddZddZddZdZ	dZ
RS(	sAn object able to transparently call methods on a remote object.

    Any method call on a L{RemoteObject} instance will return a L{Deferred}
    resulting in the return value of the same method call performed on
    the remote object exposed by the peer.
    cCs2d|_i|_||_|jj|jdS(s
        @param factory: The L{MethodCallClientFactory} used for connecting to
            the other peer. Look there if you need to tweak the behavior of
            this L{RemoteObject}.
        N(R7t_sendert_pending_requestst_factorytnotifyOnConnectt_handle_connect(RRg((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*?s			csfd}|S(s^Return a function sending a L{MethodCall} for the given C{method}.

        When the created function is called, it sends the an appropriate
        L{MethodCall} to the remote peer passing it the arguments and
        keyword arguments it was called with, and returning a L{Deferred}
        resulting in the L{MethodCall}'s response value.
        cs#t}j||||S(N(Rt_send_method_call(R>R?RA(RR!(s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRcRs	((RR!Rc((RR!s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt__getattr__JscCs|jjd|d|d|}|j|j|d||j|j||||d||jjdk	r|jjj	ndS(sASend a L{MethodCall} command, adding callbacks to handle retries.R!R>R?RNN(
RkRcR;t_handle_resultR<t_handle_failureRmtfake_connectionR7tflush(RR!R>R?RARNR#((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRpYs	
cCs*|dk	r|jn|j|dS(s&Handles a successful C{send_method_call} result.

        @param response: The L{MethodCall} response.
        @param deferred: The deferred that was returned to the caller.
        @param call: If not C{None}, the scheduled timeout call associated with
            the given deferred.
        N(R7RLRM(RR#RARN((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRris
c
Cs|jtk}|jjtk}|s-|rs||jkrO|jj|n|rb|jn|j|dS|jj	r|dkrttd}	|jjj
|jj	|j|	|||d|}n||||f|j|<dS(s+Called when a L{MethodCall} command fails.

        If a failure is due to a connection error and if C{retry_on_reconnect}
        is C{True}, we will try to perform the requested L{MethodCall} again
        as soon as a new connection becomes available, giving up after the
        specified C{timeout}, if any.

        @param failure: The L{Failure} raised by the requested L{MethodCall}.
        @param name: The method name associated with the failed L{MethodCall}.
        @param args: The positional arguments of the failed L{MethodCall}.
        @param kwargs: The keyword arguments of the failed L{MethodCall}.
        @param deferred: The deferred that was returned to the caller.
        @param call: If not C{None}, the scheduled timeout call associated with
            the given deferred.
        NRPRA(RRRmtretryOnReconnecttFalseRlR6RLRQtretryTimeoutR7RRJRSRs(
RR4R!R>R?RARNtis_method_call_errort
dont_retryRP((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRsus 

	cCs5t||jj|_|jjr1|jndS(saHandles a reconnection.

        @param protocol: The newly connected protocol instance.
        N(RFRmRJRkRvt_retry(RRI((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRoscCsg|jj}|jjxD|rb|j\}\}}}}|j||||d|qWdS(s*Try to perform again requests that failed.RNN(RltcopytcleartpopitemRp(RtrequestsRAR!R>R?RN((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR{s

	N(RRRR*RqR7RpRrRsRoR{(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRj7s		
*		tMethodCallServerFactorycBs&eZdZeZdZdZRS(s@Expose a Python object using L{MethodCall} commands over C{AMP}.cCs||_||_dS(s
        @param object: The object exposed by the L{MethodCallProtocol}s
            instances created by this factory.
        @param methods: A list of the names of the methods that remote peers
            are allowed to call on the C{object} that we publish.
        N(tobjectR/(RR.R/((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*s	cCs%|j|j|j}||_|S(N(RIRR/Rg(RtaddrRI((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt
buildProtocols	(RRRRdRIR*R(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRs	
tMethodCallClientFactorycBseZdZdZdZeZeZe	Z
dZdZ
dZdZdZdZdZdZd	Zd
ZRS(s
    Factory for L{MethodCallClientProtocol}s exposing an object or connecting
    to L{MethodCall} servers.

    When used to connect, if the connection fails or is lost the factory
    will keep retrying to establish it.

    @ivar factor: The time factor by which the delay between two subsequent
        connection retries will increase.
    @ivar maxDelay: Maximum number of seconds between connection attempts.
    @ivar protocol: The factory used to build protocol instances.
    @ivar remote: The factory used to build remote object instances.
    @ivar retryOnReconnect: If C{True}, the remote object returned by the
        C{getRemoteObject} method will retry requests that failed, as a
        result of a lost connection, as soon as a new connection is available.
    @param retryTimeout: A timeout for retrying requests, if the remote object
        can't perform them again successfully within this number of seconds,
        they will errback with a L{MethodCallError}.
    gw?icCs4||_|j|_g|_g|_d|_dS(s
        @param object: The object exposed by the L{MethodCallProtocol}s
            instances created by this factory.
        @param reactor: The reactor used by the created protocols
            to schedule notifications and timeouts.
        N(RJtinitialDelaytdelayt	_connectst	_requestsR7t_remote(RRJ((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*s
			cCs9|jdk	rt|jSt}|jj||S(sGet a L{RemoteObject} as soon as the connection is ready.

        @return: A C{Deferred} firing with a connected L{RemoteObject}.
        N(RR7RRRR8(RRA((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytgetRemoteObjects

	cCs|jj|dS(sAInvoke the given C{callback} when a connection is re-established.N(RR8(RRM((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRn	scCs|jj|dS(s,Remove the given C{callback} from listeners.N(Rtremove(RRM((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pytdontNotifyOnConnect
scCsV|jdkr$|j||_nx|jD]}||q.W|j|jdS(s2Called when a newly built protocol gets connected.N(RR7tremoteRt_fire_requests(RRIRM((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRhs
cCs6tj||||jdkr2|j|ndS(s0Try to connect again or errback pending request.N(RtclientConnectionFailedt_callIDR7R(Rt	connectortreason((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRscCs |jtj||}|S(N(t
resetDelayRR(RRRI((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR%s
cCs5|j}g|_x|D]}|j|qWdS(sY
        Fire all pending L{getRemoteObject} deferreds with the given C{result}.
        N(RRM(RR#RRA((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyR*s
	
N(RRRtfactortmaxDelayRfRIRjRRwRvR7RxRtR*RRnRRhRRR(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyRs 	
						N(%RtuuidRttwisted.internet.deferRRRttwisted.internet.protocolRRttwisted.python.failureRttwisted.protocols.ampRRR	R
RRR
tlandscape.lib.bpickleRRRRt	ExceptionRRR'R)RRFRdRfRjRR(((s5/usr/lib/python2.7/dist-packages/landscape/lib/amp.pyt<module>.s"4LW