Esempio n. 1
0
    def slice(self, streamable, protocol):
        broker  = self.requireBroker(protocol)
        puid    = ipb.IReferenceable(self.obj).processUniqueID()
        tracker = broker.getTrackerForMyReference(puid, self.obj)

        if broker.remote_broker:
            # emit a my-reference sequence
            yield b'my-reference'
            yield tracker.clid

            firstTime = tracker.send()

            if firstTime:
                # this is the first time the Referenceable has crossed this
                # wire. In addition to the clid, send the interface name (if
                # any), and any URL this reference might be known by
                iname = ipb.IRemotelyCallable(self.obj).getInterfaceName()
                yield iname or ''
                url = tracker.getURL()
                if url:
                    yield url
        else:
            # when we're serializing to data, rather than to a live
            # connection, all of my Referenceables are turned into
            # their-reference sequences, to prompt the eventual recipient to
            # create a new connection for this object.

            # a big note on object lifetimes: obviously, the data cannot keep
            # the Referenceable alive. Use tub.registerReference() on any
            # Referenceable that you want to include in the serialized data,
            # and take steps to make sure that later incarnations of this Tub
            # will do the same.
            yield b'their-reference'
            yield 0 # giftID==0 tells the recipient to not try to ack it
            yield tracker.getURL()
Esempio n. 2
0
    def _doCall(self, delivery):
        # our ordering rules require that the order in which each
        # remote_foo() method gets control is exactly the same as the order
        # in which the original caller invoked callRemote(). To insure this,
        # _startCall() is not allowed to insert additional delays before it
        # runs doRemoteCall() on the target object.
        obj = delivery.obj
        args = delivery.allargs.args
        kwargs = delivery.allargs.kwargs
        for i in args + kwargs.values():
            assert not isinstance(i, defer.Deferred)

        if delivery.methodSchema:
            # we asked about each argument on the way in, but ask again so
            # they can look for missing arguments. TODO: see if we can remove
            # the redundant per-argument checks.
            delivery.methodSchema.checkAllArgs(args, kwargs, True)

        # interesting case: if the method completes successfully, but
        # our schema prohibits us from sending the result (perhaps the
        # method returned an int but the schema insists upon a string).
        # TODO: move the return-value schema check into
        # Referenceable.doRemoteCall, so the exception's traceback will be
        # attached to the object that caused it
        if delivery.methodname is None:
            assert callable(obj)
            return obj(*args, **kwargs)
        else:
            obj = ipb.IRemotelyCallable(obj)
            return obj.doRemoteCall(delivery.methodname, args, kwargs)