Example #1
0
def test_create_future_explicit_loop(framework):
    """
    process events on alternate loop= for create_future later
    """
    pytest.importorskip('asyncio')
    if txaio.using_twisted:
        pytest.skip()

    import asyncio

    alt_loop = asyncio.new_event_loop()

    txa = txaio.with_config(loop=alt_loop)
    f = txa.create_future()

    results = []
    f.add_done_callback(lambda r: results.append(r.result()))

    assert results == []
    txaio.resolve(f, 'some result')

    # run_once() runs the txaio.config.loop so we shouldn't get any
    # results until we spin alt_loop
    assert results == []
    run_once()
    assert results == []
    with replace_loop(alt_loop):
        run_once()
    assert results == ['some result']
Example #2
0
 def on_leave(session, details):
     self.log.info(
         "session leaving '{details.reason}'",
         details=details,
     )
     if self._entry and not txaio.is_called(done):
         txaio.resolve(done, None)
Example #3
0
def test_create_future_explicit_loop(framework):
    """
    process events on alternate loop= for create_future later
    """
    pytest.importorskip('asyncio')
    if txaio.using_twisted:
        pytest.skip()

    import asyncio

    alt_loop = asyncio.new_event_loop()

    txa = txaio.with_config(loop=alt_loop)
    f = txa.create_future()

    results = []
    f.add_done_callback(lambda r: results.append(r.result()))

    assert results == []
    txaio.resolve(f, 'some result')

    # run_once() runs the txaio.config.loop so we shouldn't get any
    # results until we spin alt_loop
    assert results == []
    run_once()
    assert results == []
    with replace_loop(alt_loop):
        run_once()
    assert results == ['some result']
 def on_leave(session, details):
     self.log.info(
         "session leaving '{details.reason}'",
         details=details,
     )
     if self._entry and not txaio.is_called(done):
         txaio.resolve(done, None)
Example #5
0
                def on_disconnect(session, was_clean):
                    self.log.debug("session on_disconnect: {was_clean}", was_clean=was_clean)

                    if was_clean:
                        # eg the session has left the realm, and the transport was properly
                        # shut down. successfully finish the connection
                        txaio.resolve(done, None)
                    else:
                        txaio.reject(done, RuntimeError('transport closed uncleanly'))
Example #6
0
 def on_leave(session, details):
     self.log.debug("session on_leave: {details}", details=details)
     # this could be a "leave" that's expected e.g. our
     # main() exited, or it could be an error
     if not txaio.is_called(done):
         if details.reason.startswith('wamp.error.'):
             txaio.reject(done, ApplicationError(details.reason, details.message))
         else:
             txaio.resolve(done, None)
Example #7
0
                def on_disconnect(session, was_clean):
                    self.log.debug("session on_disconnect: {was_clean}", was_clean=was_clean)

                    if was_clean:
                        # eg the session has left the realm, and the transport was properly
                        # shut down. successfully finish the connection
                        txaio.resolve(done, None)
                    else:
                        txaio.reject(done, RuntimeError('transport closed uncleanly'))
            def process(signature_raw):
                # convert the raw signature into a hex encode value (unicode string)
                signature_hex = binascii.b2a_hex(signature_raw).decode('ascii')

                # we return the concatenation of the signature and the message signed (96 bytes)
                data_hex = binascii.b2a_hex(data).decode('ascii')

                sig = signature_hex + data_hex
                txaio.resolve(d2, sig)
Example #9
0
            def process(signature_raw):
                # convert the raw signature into a hex encode value (unicode string)
                signature_hex = binascii.b2a_hex(signature_raw).decode('ascii')

                # we return the concatenation of the signature and the message signed (96 bytes)
                data_hex = binascii.b2a_hex(data).decode('ascii')

                sig = signature_hex + data_hex
                txaio.resolve(d2, sig)
Example #10
0
 async def onJoin(self, details):
     self.log.info('Ok, client joined on realm "{realm}" [session={session}, authid="{authid}", authrole="{authrole}"]',
                   realm=hlid(details.realm),
                   session=hlid(details.session),
                   authid=hlid(details.authid),
                   authrole=hlid(details.authrole),
                   details=details)
     if 'ready' in self.config.extra:
         txaio.resolve(self.config.extra['ready'], (self, details))
Example #11
0
 def connectionLost(self, reason):
     self.log.debug("WampRawSocketProtocol: connection lost: reason = '{reason}'", reason=reason)
     txaio.resolve(self.is_closed, self)
     try:
         wasClean = isinstance(reason.value, ConnectionDone)
         self._session.onClose(wasClean)
     except Exception as e:
         # silently ignore exceptions raised here ..
         self.log.warn("WampRawSocketProtocol: ApplicationSession.onClose raised ({err})", err=e)
     self._session = None
Example #12
0
 def methodReturnReceived(self, mret):
     """
     Called when a method return message is received
     """
     d, timeout = self._pendingCalls.get(mret.reply_serial, (None,None))
     if timeout:
         timeout.cancel()
     if d:
         del self._pendingCalls[ mret.reply_serial ]
         txaio.resolve(d, mret)
Example #13
0
 def on_disconnect(session, was_clean):
     self.log.debug(
         "session on_disconnect: was_clean={was_clean}",
         was_clean=was_clean,
     )
     if not txaio.is_called(done):
         if not was_clean:
             self.log.warn(u"Session disconnected uncleanly")
         # eg the session has left the realm, and the transport was properly
         # shut down. successfully finish the connection
         txaio.resolve(done, None)
Example #14
0
 def connectionLost(self, reason):
     self.log.debug("WampRawSocketProtocol: connection lost: reason = '{reason}'", reason=reason)
     txaio.resolve(self.is_closed, self)
     try:
         wasClean = isinstance(reason.value, ConnectionDone)
         if self._session:
             self._session.onClose(wasClean)
     except Exception as e:
         # silently ignore exceptions raised here ..
         self.log.warn("WampRawSocketProtocol: ApplicationSession.onClose raised ({err})", err=e)
     self._session = None
Example #15
0
                            def _notify_some(receivers):

                                # we do a first pass over the proposed chunk of receivers
                                # because not all of them will have a transport, and if this
                                # will be the last chunk of receivers we need to figure out
                                # which event is last...
                                receivers_this_chunk = []
                                for receiver in receivers[:chunk_size]:
                                    if receiver._session_id and receiver._transport:
                                        receivers_this_chunk.append(receiver)
                                    else:
                                        vanished_receivers.append(receiver)

                                receivers = receivers[chunk_size:]

                                # XXX note there's still going to be some edge-cases here .. if
                                # we are NOT the last chunk, but all the next chunk's receivers
                                # (could be only 1 in that chunk!) vanish before we run our next
                                # batch, then a "last" event will never go out ...

                                # we now actually do the deliveries, but now we know which
                                # receiver is the last one
                                if receivers or not self._router.is_traced:

                                    # NOT the last chunk (or we're not traced so don't care)
                                    for receiver in receivers_this_chunk:

                                        # send out WAMP msg to peer
                                        self._router.send(receiver, msg)
                                        if self._event_store or storing_event:
                                            self._event_store.store_event_history(publication, subscription.id, receiver)
                                else:
                                    # last chunk, so last receiver gets the different message
                                    for receiver in receivers_this_chunk[:-1]:
                                        self._router.send(receiver, msg)
                                        if self._event_store or storing_event:
                                            self._event_store.store_event_history(publication, subscription.id, receiver)

                                    # FIXME: I don't get the following comment and code path. when, how? and what to
                                    # do about event store? => storing_event
                                    #
                                    # we might have zero valid receivers
                                    if receivers_this_chunk:
                                        self._router.send(receivers_this_chunk[-1], last_msg)
                                        # FIXME: => storing_event

                                if receivers:
                                    # still more to do ..
                                    return txaio.call_later(0, _notify_some, receivers)
                                else:
                                    # all done! resolve all_d, which represents all receivers
                                    # to a single subscription matching the event
                                    txaio.resolve(all_d, None)
Example #16
0
 def on_leave(session, details):
     self.log.info(
         "session leaving '{details.reason}'",
         details=details,
     )
     if not txaio.is_called(done):
         if details.reason in [u"wamp.close.normal"]:
             txaio.resolve(done, None)
         else:
             f = txaio.create_failure(
                 ApplicationError(details.reason))
             txaio.reject(done, f)
Example #17
0
 def connectionLost(self, reason):
     self.log.debug('{klass}.connectionLost(reason="{reason}"', klass=self.__class__.__name__, reason=reason)
     txaio.resolve(self.is_closed, self)
     try:
         wasClean = isinstance(reason.value, ConnectionDone)
         if self._session:
             self._session.onClose(wasClean)
     except Exception as e:
         # silently ignore exceptions raised here ..
         self.log.warn('{klass}.connectionLost(): ApplicationSession.onClose raised "{err}"',
                       klass=self.__class__.__name__, err=e)
     self._session = None
 def error(fail):
     self._delay_f = None
     if self._stopping:
         # might be better to add framework-specific checks in
         # subclasses to see if this is CancelledError (for
         # Twisted) and whatever asyncio does .. but tracking
         # if we're in the shutdown path is fine too
         txaio.resolve(self._done_f, None)
     else:
         self.log.info("Internal error {msg}", msg=txaio.failure_message(fail))
         self.log.debug("{tb}", tb=txaio.failure_format_traceback(fail))
         txaio.reject(self._done_f, fail)
Example #19
0
 def error(fail):
     self._delay_f = None
     if self._stopping:
         # might be better to add framework-specific checks in
         # subclasses to see if this is CancelledError (for
         # Twisted) and whatever asyncio does .. but tracking
         # if we're in the shutdown path is fine too
         txaio.resolve(self._done_f, None)
     else:
         self.log.info("Internal error {msg}", msg=txaio.failure_message(fail))
         self.log.debug("{tb}", tb=txaio.failure_format_traceback(fail))
         txaio.reject(self._done_f, fail)
Example #20
0
                            def _notify_some(receivers):

                                # we do a first pass over the proposed chunk of receivers
                                # because not all of them will have a transport, and if this
                                # will be the last chunk of receivers we need to figure out
                                # which event is last...
                                receivers_this_chunk = []
                                for receiver in receivers[:chunk_size]:
                                    if receiver._session_id and receiver._transport:
                                        receivers_this_chunk.append(receiver)
                                    else:
                                        vanished_receivers.append(receiver)

                                receivers = receivers[chunk_size:]

                                # XXX note there's still going to be some edge-cases here .. if
                                # we are NOT the last chunk, but all the next chunk's receivers
                                # (could be only 1 in that chunk!) vanish before we run our next
                                # batch, then a "last" event will never go out ...

                                # we now actually do the deliveries, but now we know which
                                # receiver is the last one
                                if receivers or not self._router.is_traced:

                                    # NOT the last chunk (or we're not traced so don't care)
                                    for receiver in receivers_this_chunk:

                                        # send out WAMP msg to peer
                                        self._router.send(receiver, msg)
                                        if self._event_store or storing_event:
                                            self._event_store.store_event_history(publication, subscription.id, receiver)
                                else:
                                    # last chunk, so last receiver gets the different message
                                    for receiver in receivers_this_chunk[:-1]:
                                        self._router.send(receiver, msg)
                                        if self._event_store or storing_event:
                                            self._event_store.store_event_history(publication, subscription.id, receiver)

                                    # FIXME: I don't get the following comment and code path. when, how? and what to
                                    # do about event store? => storing_event
                                    #
                                    # we might have zero valid receivers
                                    if receivers_this_chunk:
                                        self._router.send(receivers_this_chunk[-1], last_msg)
                                        # FIXME: => storing_event

                                if receivers:
                                    # still more to do ..
                                    return txaio.call_later(0, _notify_some, receivers)
                                else:
                                    # all done! resolve all_d, which represents all receivers
                                    # to a single subscription matching the event
                                    txaio.resolve(all_d, None)
Example #21
0
    async def onJoin(self, details):  # noqa: N802
        self.log.info('{klass}.onJoin(details={details})',
                      klass=self.__class__.__name__,
                      details=details)

        done = self.config.extra.get('done', None)

        result = None
        error = None
        if self._command:
            self.log.info('{klass}: running command {command}',
                          klass=self.__class__.__name__,
                          command=self._command)
            try:
                result = await self._command.run(self)
                self.log.info('command run with result {result}',
                              result=result)
            except Exception as e:
                self.log.warn('command failed: {error}', error=e)
                error = e
        elif self._main:
            self.log.info('{klass}: running main function {main}',
                          klass=self.__class__.__name__,
                          main=self._main)
            try:
                result = await self._main(self)
                self.log.info('main run with result {result}', result=result)
            except Exception as e:
                self.log.warn('main failed: {error}', error=e)
                error = e
        else:
            self.log.info('{klass}: no command or main function to run!',
                          klass=self.__class__.__name__)

        if done and not txaio.is_called(done):
            if error:
                self.log.warn('{klass}: command returned with error ({error})',
                              klass=self.__class__.__name__,
                              error=error)
                txaio.reject(done, error)
            else:
                self.log.info(
                    '{klass}: command returned with success ({result})',
                    klass=self.__class__.__name__,
                    result=result)
                txaio.resolve(done, (details, result))

        self.log.info('{klass}.onJoin(): finished!',
                      klass=self.__class__.__name__)

        if self._main:
            self.leave()
Example #22
0
 def on_leave(session, details):
     self.log.debug("session on_leave: {details}",
                    details=details)
     # this could be a "leave" that's expected e.g. our
     # main() exited, or it could be an error
     if not txaio.is_called(done):
         if details.reason.startswith('wamp.error.'):
             txaio.reject(
                 done,
                 ApplicationError(details.reason,
                                  details.message))
         else:
             txaio.resolve(done, None)
Example #23
0
 def on_leave(session, details):
     self.log.info(
         "session leaving '{details.reason}'",
         details=details,
     )
     if not txaio.is_called(done):
         if details.reason in [u"wamp.close.normal"]:
             txaio.resolve(done, None)
         else:
             f = txaio.create_failure(
                 ApplicationError(details.reason)
             )
             txaio.reject(done, f)
Example #24
0
def test_callback(framework):
    f = txaio.create_future()
    results = []

    def cb(f):
        results.append(f)
    txaio.add_callbacks(f, cb, None)
    txaio.resolve(f, "it worked")

    run_once()

    assert len(results) == 1
    assert results[0] == "it worked"
Example #25
0
 def on_disconnect(session, was_clean):
     self.log.debug(
         "session on_disconnect: was_clean={was_clean}",
         was_clean=was_clean,
     )
     if not txaio.is_called(done):
         if not was_clean:
             self.log.warn(
                 u"Session disconnected uncleanly"
             )
         # eg the session has left the realm, and the transport was properly
         # shut down. successfully finish the connection
         txaio.resolve(done, None)
Example #26
0
 def _notify_some(receivers):
     for receiver in receivers[:chunk_size]:
         if (me_also or receiver != session) and receiver != self._event_store:
             # the receiving subscriber session
             # might have no transport, or no
             # longer be joined
             if receiver._session_id and receiver._transport:
                 self._router.send(receiver, msg)
     receivers = receivers[chunk_size:]
     if len(receivers) > 0:
         return txaio.call_later(0, _notify_some, receivers)
     else:
         txaio.resolve(all_d, None)
Example #27
0
 def on_leave(session, details):
     self.log.info(
         "session leaving '{details.reason}'",
         details=details,
     )
     if not txaio.is_called(done):
         if details.reason in [u"wamp.error.no_auth_method"]:
             txaio.resolve(done, txaio.create_failure(
                 ApplicationError(
                     u"wamp.error.no_auth_method"
                 )
             ))
         else:
             txaio.resolve(done, None)
Example #28
0
 def on_leave(session, details):
     self.log.info(
         "session leaving '{details.reason}'",
         details=details,
     )
     if not txaio.is_called(done):
         if details.reason in [u"wamp.error.no_auth_method"]:
             txaio.resolve(done, txaio.create_failure(
                 ApplicationError(
                     u"wamp.error.no_auth_method"
                 )
             ))
         else:
             txaio.resolve(done, None)
Example #29
0
def test_callback(framework):
    f = txaio.create_future()
    results = []

    def cb(f):
        results.append(f)

    txaio.add_callbacks(f, cb, None)
    txaio.resolve(f, "it worked")

    run_once()

    assert len(results) == 1
    assert results[0] == "it worked"
Example #30
0
 def stop(self):
     self._stopping = True
     if self._session and self._session.is_attached():
         return self._session.leave()
     elif self._delay_f:
         # This cancel request will actually call the "error" callback of
         # the _delay_f future. Nothing to worry about.
         return txaio.as_future(txaio.cancel, self._delay_f)
     # if (for some reason -- should we log warning here to figure
     # out if this can evern happen?) we've not fired _done_f, we
     # do that now (causing our "main" to exit, and thus react() to
     # quit)
     if not txaio.is_called(self._done_f):
         txaio.resolve(self._done_f, None)
     return txaio.create_future_success(None)
Example #31
0
 def stop(self):
     self._stopping = True
     if self._session and self._session.is_attached():
         return self._session.leave()
     elif self._delay_f:
         # This cancel request will actually call the "error" callback of
         # the _delay_f future. Nothing to worry about.
         return txaio.as_future(txaio.cancel, self._delay_f)
     # if (for some reason -- should we log warning here to figure
     # out if this can evern happen?) we've not fired _done_f, we
     # do that now (causing our "main" to exit, and thus react() to
     # quit)
     if not txaio.is_called(self._done_f):
         txaio.resolve(self._done_f, None)
     return txaio.create_future_success(None)
Example #32
0
                            def _notify_some(receivers):

                                # we do a first pass over the proposed chunk of receivers
                                # because not all of them will have a transport, and if this
                                # will be the last chunk of receivers we need to figure out
                                # which event is last...
                                receivers_this_chunk = []
                                for receiver in receivers[:chunk_size]:
                                    if (me_also or receiver != session
                                        ) and receiver != self._event_store:
                                        # the receiving subscriber session might have no transport,
                                        # or no longer be joined
                                        if receiver._session_id and receiver._transport:
                                            receivers_this_chunk.append(
                                                receiver)
                                        else:
                                            vanished_receivers.append(receiver)

                                receivers = receivers[chunk_size:]

                                # XXX note there's still going to be some edge-cases here .. if
                                # we are NOT the last chunk, but all the next chunk's receivers
                                # (could be only 1 in that chunk!) vanish before we run our next
                                # batch, then a "last" event will never go out ...

                                # we now actually do the deliveries, but now we know which
                                # receiver is the last one
                                if receivers or not self._router.is_traced:
                                    # NOT the last chunk (or we're not traced so don't care)
                                    for receiver in receivers_this_chunk:
                                        self._router.send(receiver, msg)
                                else:
                                    # last chunk, so last receiver gets the different message
                                    for receiver in receivers_this_chunk[:-1]:
                                        self._router.send(receiver, msg)
                                    # we might have zero valid receivers
                                    if receivers_this_chunk:
                                        self._router.send(
                                            receivers_this_chunk[-1], last_msg)

                                if receivers:
                                    # still more to do ..
                                    return txaio.call_later(
                                        0, _notify_some, receivers)
                                else:
                                    # all done! resolve all_d, which represents all receivers
                                    # to a single subscription matching the event
                                    txaio.resolve(all_d, None)
Example #33
0
 def _notify_some(receivers):
     for receiver in receivers[:chunk_size]:
         if (
                 me_also or receiver != session
         ) and receiver != self._event_store:
             # the receiving subscriber session
             # might have no transport, or no
             # longer be joined
             if receiver._session_id and receiver._transport:
                 self._router.send(
                     receiver, msg)
     receivers = receivers[chunk_size:]
     if len(receivers) > 0:
         # still more to do ..
         return txaio.call_later(
             0, _notify_some, receivers)
     else:
         # all done! resolve all_d, which represents all receivers
         # to a single subscription matching the event
         txaio.resolve(all_d, None)
Example #34
0
def test_chained_callback(framework):
    """
    Chain two callbacks where the first one alters the value.
    """
    calls = []

    def callback0(arg):
        calls.append(arg)
        return arg + " pray I do not alter it futher"

    def callback1(arg):
        calls.append(arg)

    f = txaio.create_future()
    txaio.add_callbacks(f, callback0, None)
    txaio.add_callbacks(f, callback1, None)
    txaio.resolve(f, "the deal")

    run_once()

    assert len(calls) == 2
    assert calls[0] == "the deal"
    assert calls[1] == "the deal pray I do not alter it futher"
Example #35
0
def test_chained_callback(framework):
    """
    Chain two callbacks where the first one alters the value.
    """
    calls = []

    def callback0(arg):
        calls.append(arg)
        return arg + " pray I do not alter it futher"

    def callback1(arg):
        calls.append(arg)

    f = txaio.create_future()
    txaio.add_callbacks(f, callback0, None)
    txaio.add_callbacks(f, callback1, None)
    txaio.resolve(f, "the deal")

    run_once()

    assert len(calls) == 2
    assert calls[0] == "the deal"
    assert calls[1] == "the deal pray I do not alter it futher"
Example #36
0
File: basic.py Project: koobs/txaio
from __future__ import print_function
import txaio

def cb(value):
    print("Callback:", value)
    return value  # should always return input arg

def eb(fail):
    # fail will implement txaio.IFailedPromise
    print("Errback:", fail)
    # fail.printTraceback()
    return fail  # should always return input arg

f0 = txaio.create_future()
f1 = txaio.create_future()
txaio.add_callbacks(f0, cb, eb)
txaio.add_callbacks(f1, cb, eb)

# ...

txaio.reject(f0, RuntimeError("it failed"))
# or can just "txaio.reject(f0)" if inside an except: block
txaio.resolve(f1, "The answer is: 42")

if txaio.using_asyncio:
    # for twisted, we don't need to enter the event-loop for this
    # simple example (since all results are already available), but
    # you'd simply use reactor.run()/.stop() or task.react() as normal
    import asyncio
    asyncio.get_event_loop().run_until_complete(f1)
Example #37
0
 def main_success(_):
     self.log.debug("main_success")
     txaio.resolve(done, None)
Example #38
0
 def _cb(arg):
     txaio.resolve(d, arg)
Example #39
0
 def session_done(x):
     txaio.resolve(self._done_f, None)
 def foo(x):
     f = txaio.create_future()
     txaio.resolve(f, x * x)
     return f
Example #41
0
 def onClose(self, wasClean, code, reason):
     txaio.resolve(self.factory._done, None)
 def foo(x):
     f = txaio.create_future()
     txaio.resolve(f, x * x)
     return f
    def onMessage(self, msg):
        """
        Implements :func:`autobahn.wamp.interfaces.ITransportHandler.onMessage`
        """
        if self._session_id is None:

            # the first message must be WELCOME, ABORT or CHALLENGE ..
            if isinstance(msg, message.Welcome):
                self._session_id = msg.session

                details = SessionDetails(self._realm, self._session_id, msg.authid, msg.authrole, msg.authmethod)
                d = txaio.as_future(self.onJoin, details)

                def _error(e):
                    return self._swallow_error(e, "While firing onJoin")
                txaio.add_callbacks(d, None, _error)

            elif isinstance(msg, message.Abort):

                # fire callback and close the transport
                details = types.CloseDetails(msg.reason, msg.message)
                d = txaio.as_future(self.onLeave, details)

                def _error(e):
                    return self._swallow_error(e, "While firing onLeave")
                txaio.add_callbacks(d, None, _error)

            elif isinstance(msg, message.Challenge):

                challenge = types.Challenge(msg.method, msg.extra)
                d = txaio.as_future(self.onChallenge, challenge)

                def success(signature):
                    reply = message.Authenticate(signature)
                    self._transport.send(reply)

                def error(err):
                    reply = message.Abort(u"wamp.error.cannot_authenticate", u"{0}".format(err.value))
                    self._transport.send(reply)
                    # fire callback and close the transport
                    details = types.CloseDetails(reply.reason, reply.message)
                    d = txaio.as_future(self.onLeave, details)

                    def _error(e):
                        return self._swallow_error(e, "While firing onLeave")
                    txaio.add_callbacks(d, None, _error)
                    # switching to the callback chain, effectively
                    # cancelling error (which we've now handled)
                    return d

                txaio.add_callbacks(d, success, error)

            else:
                raise ProtocolError("Received {0} message, and session is not yet established".format(msg.__class__))

        else:
            # self._session_id != None (aka "session established")
            if isinstance(msg, message.Goodbye):
                if not self._goodbye_sent:
                    # the peer wants to close: send GOODBYE reply
                    reply = message.Goodbye()
                    self._transport.send(reply)

                self._session_id = None

                # fire callback and close the transport
                details = types.CloseDetails(msg.reason, msg.message)
                d = txaio.as_future(self.onLeave, details)

                def _error(e):
                    errmsg = 'While firing onLeave for reason "{0}" and message "{1}"'.format(msg.reason, msg.message)
                    return self._swallow_error(e, errmsg)
                txaio.add_callbacks(d, None, _error)

            elif isinstance(msg, message.Event):

                if msg.subscription in self._subscriptions:

                    # fire all event handlers on subscription ..
                    for subscription in self._subscriptions[msg.subscription]:

                        handler = subscription.handler

                        invoke_args = (handler.obj,) if handler.obj else tuple()
                        if msg.args:
                            invoke_args = invoke_args + tuple(msg.args)

                        invoke_kwargs = msg.kwargs if msg.kwargs else dict()
                        if handler.details_arg:
                            invoke_kwargs[handler.details_arg] = types.EventDetails(publication=msg.publication, publisher=msg.publisher, topic=msg.topic)

                        def _error(e):
                            errmsg = 'While firing {0} subscribed under {1}.'.format(
                                handler.fn, msg.subscription)
                            return self._swallow_error(e, errmsg)

                        future = txaio.as_future(handler.fn, *invoke_args, **invoke_kwargs)
                        txaio.add_callbacks(future, None, _error)

                else:
                    raise ProtocolError("EVENT received for non-subscribed subscription ID {0}".format(msg.subscription))

            elif isinstance(msg, message.Published):

                if msg.request in self._publish_reqs:

                    # get and pop outstanding publish request
                    publish_request = self._publish_reqs.pop(msg.request)

                    # create a new publication object
                    publication = Publication(msg.publication)

                    # resolve deferred/future for publishing successfully
                    txaio.resolve(publish_request.on_reply, publication)
                else:
                    raise ProtocolError("PUBLISHED received for non-pending request ID {0}".format(msg.request))

            elif isinstance(msg, message.Subscribed):

                if msg.request in self._subscribe_reqs:

                    # get and pop outstanding subscribe request
                    request = self._subscribe_reqs.pop(msg.request)

                    # create new handler subscription list for subscription ID if not yet tracked
                    if msg.subscription not in self._subscriptions:
                        self._subscriptions[msg.subscription] = []

                    subscription = Subscription(msg.subscription, self, request.handler)

                    # add handler to existing subscription
                    self._subscriptions[msg.subscription].append(subscription)

                    # resolve deferred/future for subscribing successfully
                    txaio.resolve(request.on_reply, subscription)
                else:
                    raise ProtocolError("SUBSCRIBED received for non-pending request ID {0}".format(msg.request))

            elif isinstance(msg, message.Unsubscribed):

                if msg.request in self._unsubscribe_reqs:

                    # get and pop outstanding subscribe request
                    request = self._unsubscribe_reqs.pop(msg.request)

                    # if the subscription still exists, mark as inactive and remove ..
                    if request.subscription_id in self._subscriptions:
                        for subscription in self._subscriptions[request.subscription_id]:
                            subscription.active = False
                        del self._subscriptions[request.subscription_id]

                    # resolve deferred/future for unsubscribing successfully
                    txaio.resolve(request.on_reply, 0)
                else:
                    raise ProtocolError("UNSUBSCRIBED received for non-pending request ID {0}".format(msg.request))

            elif isinstance(msg, message.Result):

                if msg.request in self._call_reqs:

                    if msg.progress:

                        # progressive result
                        call_request = self._call_reqs[msg.request]
                        if call_request.options.on_progress:
                            kw = msg.kwargs or dict()
                            args = msg.args or tuple()
                            try:
                                # XXX what if on_progress returns a Deferred/Future?
                                call_request.options.on_progress(*args, **kw)
                            except Exception as e:
                                try:
                                    self.onUserError(e, "While firing on_progress")
                                except:
                                    pass

                        else:
                            # silently ignore progressive results
                            pass

                    else:
                        # final result
                        #
                        call_request = self._call_reqs.pop(msg.request)

                        on_reply = call_request.on_reply

                        if msg.kwargs:
                            if msg.args:
                                res = types.CallResult(*msg.args, **msg.kwargs)
                            else:
                                res = types.CallResult(**msg.kwargs)
                            txaio.resolve(on_reply, res)
                        else:
                            if msg.args:
                                if len(msg.args) > 1:
                                    res = types.CallResult(*msg.args)
                                    txaio.resolve(on_reply, res)
                                else:
                                    txaio.resolve(on_reply, msg.args[0])
                            else:
                                txaio.resolve(on_reply, None)
                else:
                    raise ProtocolError("RESULT received for non-pending request ID {0}".format(msg.request))

            elif isinstance(msg, message.Invocation):

                if msg.request in self._invocations:

                    raise ProtocolError("INVOCATION received for request ID {0} already invoked".format(msg.request))

                else:

                    if msg.registration not in self._registrations:

                        raise ProtocolError("INVOCATION received for non-registered registration ID {0}".format(msg.registration))

                    else:
                        registration = self._registrations[msg.registration]

                        endpoint = registration.endpoint

                        if endpoint.obj:
                            invoke_args = (endpoint.obj,)
                        else:
                            invoke_args = tuple()

                        if msg.args:
                            invoke_args = invoke_args + tuple(msg.args)

                        invoke_kwargs = msg.kwargs if msg.kwargs else dict()

                        if endpoint.details_arg:

                            if msg.receive_progress:
                                def progress(*args, **kwargs):
                                    progress_msg = message.Yield(msg.request, args=args, kwargs=kwargs, progress=True)
                                    self._transport.send(progress_msg)
                            else:
                                progress = None

                            invoke_kwargs[endpoint.details_arg] = types.CallDetails(progress, caller=msg.caller, procedure=msg.procedure)

                        on_reply = txaio.as_future(endpoint.fn, *invoke_args, **invoke_kwargs)

                        def success(res):
                            del self._invocations[msg.request]

                            if isinstance(res, types.CallResult):
                                reply = message.Yield(msg.request, args=res.results, kwargs=res.kwresults)
                            else:
                                reply = message.Yield(msg.request, args=[res])

                            try:
                                self._transport.send(reply)
                            except SerializationError as e:
                                # the application-level payload returned from the invoked procedure can't be serialized
                                reply = message.Error(message.Invocation.MESSAGE_TYPE, msg.request, ApplicationError.INVALID_PAYLOAD,
                                                      args=[u'success return value from invoked procedure "{0}" could not be serialized: {1}'.format(registration.procedure, e)])
                                self._transport.send(reply)

                        def error(err):
                            errmsg = 'Failure while invoking procedure {0} registered under "{1}".'.format(endpoint.fn, registration.procedure)
                            try:
                                self.onUserError(err, errmsg)
                            except:
                                pass
                            formatted_tb = None
                            if self.traceback_app:
                                # if asked to marshal the traceback within the WAMP error message, extract it
                                # noinspection PyCallingNonCallable
                                tb = StringIO()
                                err.printTraceback(file=tb)
                                formatted_tb = tb.getvalue().splitlines()

                            del self._invocations[msg.request]

                            if hasattr(err, 'value'):
                                exc = err.value
                            else:
                                exc = err

                            reply = self._message_from_exception(message.Invocation.MESSAGE_TYPE, msg.request, exc, formatted_tb)

                            try:
                                self._transport.send(reply)
                            except SerializationError as e:
                                # the application-level payload returned from the invoked procedure can't be serialized
                                reply = message.Error(message.Invocation.MESSAGE_TYPE, msg.request, ApplicationError.INVALID_PAYLOAD,
                                                      args=[u'error return value from invoked procedure "{0}" could not be serialized: {1}'.format(registration.procedure, e)])
                                self._transport.send(reply)
                            # we have handled the error, so we eat it
                            return None

                        self._invocations[msg.request] = InvocationRequest(msg.request, on_reply)

                        txaio.add_callbacks(on_reply, success, error)

            elif isinstance(msg, message.Interrupt):

                if msg.request not in self._invocations:
                    raise ProtocolError("INTERRUPT received for non-pending invocation {0}".format(msg.request))
                else:
                    # noinspection PyBroadException
                    try:
                        self._invocations[msg.request].cancel()
                    except Exception as e:
                        # XXX can .cancel() return a Deferred/Future?
                        try:
                            self.onUserError(e, "While cancelling call.")
                        except:
                            pass
                    finally:
                        del self._invocations[msg.request]

            elif isinstance(msg, message.Registered):

                if msg.request in self._register_reqs:

                    # get and pop outstanding register request
                    request = self._register_reqs.pop(msg.request)

                    # create new registration if not yet tracked
                    if msg.registration not in self._registrations:
                        registration = Registration(self, msg.registration, request.procedure, request.endpoint)
                        self._registrations[msg.registration] = registration
                    else:
                        raise ProtocolError("REGISTERED received for already existing registration ID {0}".format(msg.registration))

                    txaio.resolve(request.on_reply, registration)
                else:
                    raise ProtocolError("REGISTERED received for non-pending request ID {0}".format(msg.request))

            elif isinstance(msg, message.Unregistered):

                if msg.request in self._unregister_reqs:

                    # get and pop outstanding subscribe request
                    request = self._unregister_reqs.pop(msg.request)

                    # if the registration still exists, mark as inactive and remove ..
                    if request.registration_id in self._registrations:
                        self._registrations[request.registration_id].active = False
                        del self._registrations[request.registration_id]

                    # resolve deferred/future for unregistering successfully
                    txaio.resolve(request.on_reply)
                else:
                    raise ProtocolError("UNREGISTERED received for non-pending request ID {0}".format(msg.request))

            elif isinstance(msg, message.Error):

                # remove outstanding request and get the reply deferred/future
                on_reply = None

                # ERROR reply to CALL
                if msg.request_type == message.Call.MESSAGE_TYPE and msg.request in self._call_reqs:
                    on_reply = self._call_reqs.pop(msg.request).on_reply

                # ERROR reply to PUBLISH
                elif msg.request_type == message.Publish.MESSAGE_TYPE and msg.request in self._publish_reqs:
                    on_reply = self._publish_reqs.pop(msg.request).on_reply

                # ERROR reply to SUBSCRIBE
                elif msg.request_type == message.Subscribe.MESSAGE_TYPE and msg.request in self._subscribe_reqs:
                    on_reply = self._subscribe_reqs.pop(msg.request).on_reply

                # ERROR reply to UNSUBSCRIBE
                elif msg.request_type == message.Unsubscribe.MESSAGE_TYPE and msg.request in self._unsubscribe_reqs:
                    on_reply = self._unsubscribe_reqs.pop(msg.request).on_reply

                # ERROR reply to REGISTER
                elif msg.request_type == message.Register.MESSAGE_TYPE and msg.request in self._register_reqs:
                    on_reply = self._register_reqs.pop(msg.request).on_reply

                # ERROR reply to UNREGISTER
                elif msg.request_type == message.Unregister.MESSAGE_TYPE and msg.request in self._unregister_reqs:
                    on_reply = self._unregister_reqs.pop(msg.request).on_reply

                if on_reply:
                    txaio.reject(on_reply, self._exception_from_message(msg))
                else:
                    raise ProtocolError("WampAppSession.onMessage(): ERROR received for non-pending request_type {0} and request ID {1}".format(msg.request_type, msg.request))

            else:

                raise ProtocolError("Unexpected message {0}".format(msg.__class__))
 def onClose(self, wasClean, code, reason):
     txaio.resolve(self.factory._done, None)
 def onJoin(self, details):
     txaio.resolve(d, None)
Example #46
0
    def onMessage(self, msg):
        """
        Implements :func:`autobahn.wamp.interfaces.ITransportHandler.onMessage`
        """
        if self._session_id is None:

            # the first message must be WELCOME, ABORT or CHALLENGE ..
            if isinstance(msg, message.Welcome):
                self._session_id = msg.session

                details = SessionDetails(self._realm, self._session_id,
                                         msg.authid, msg.authrole,
                                         msg.authmethod)
                d = txaio.as_future(self.onJoin, details)

                def _error(e):
                    return self._swallow_error(e, "While firing onJoin")

                txaio.add_callbacks(d, None, _error)

            elif isinstance(msg, message.Abort):

                # fire callback and close the transport
                details = types.CloseDetails(msg.reason, msg.message)
                d = txaio.as_future(self.onLeave, details)

                def _error(e):
                    return self._swallow_error(e, "While firing onLeave")

                txaio.add_callbacks(d, None, _error)

            elif isinstance(msg, message.Challenge):

                challenge = types.Challenge(msg.method, msg.extra)
                d = txaio.as_future(self.onChallenge, challenge)

                def success(signature):
                    if not isinstance(signature, six.text_type):
                        raise Exception('signature must be unicode')
                    reply = message.Authenticate(signature)
                    self._transport.send(reply)

                def error(err):
                    self.onUserError(err, "Authentication failed")
                    reply = message.Abort(u"wamp.error.cannot_authenticate",
                                          u"{0}".format(err.value))
                    self._transport.send(reply)
                    # fire callback and close the transport
                    details = types.CloseDetails(reply.reason, reply.message)
                    d = txaio.as_future(self.onLeave, details)

                    def _error(e):
                        return self._swallow_error(e, "While firing onLeave")

                    txaio.add_callbacks(d, None, _error)
                    # switching to the callback chain, effectively
                    # cancelling error (which we've now handled)
                    return d

                txaio.add_callbacks(d, success, error)

            else:
                raise ProtocolError(
                    "Received {0} message, and session is not yet established".
                    format(msg.__class__))

        else:
            # self._session_id != None (aka "session established")
            if isinstance(msg, message.Goodbye):
                if not self._goodbye_sent:
                    # the peer wants to close: send GOODBYE reply
                    reply = message.Goodbye()
                    self._transport.send(reply)

                self._session_id = None

                # fire callback and close the transport
                details = types.CloseDetails(msg.reason, msg.message)
                d = txaio.as_future(self.onLeave, details)

                def _error(e):
                    errmsg = 'While firing onLeave for reason "{0}" and message "{1}"'.format(
                        msg.reason, msg.message)
                    return self._swallow_error(e, errmsg)

                txaio.add_callbacks(d, None, _error)

            elif isinstance(msg, message.Event):

                if msg.subscription in self._subscriptions:

                    # fire all event handlers on subscription ..
                    for subscription in self._subscriptions[msg.subscription]:

                        handler = subscription.handler

                        invoke_args = (
                            handler.obj, ) if handler.obj else tuple()
                        if msg.args:
                            invoke_args = invoke_args + tuple(msg.args)

                        invoke_kwargs = msg.kwargs if msg.kwargs else dict()
                        if handler.details_arg:
                            invoke_kwargs[
                                handler.details_arg] = types.EventDetails(
                                    publication=msg.publication,
                                    publisher=msg.publisher,
                                    topic=msg.topic or subscription.topic)

                        def _error(e):
                            errmsg = 'While firing {0} subscribed under {1}.'.format(
                                handler.fn, msg.subscription)
                            return self._swallow_error(e, errmsg)

                        future = txaio.as_future(handler.fn, *invoke_args,
                                                 **invoke_kwargs)
                        txaio.add_callbacks(future, None, _error)

                else:
                    raise ProtocolError(
                        "EVENT received for non-subscribed subscription ID {0}"
                        .format(msg.subscription))

            elif isinstance(msg, message.Published):

                if msg.request in self._publish_reqs:

                    # get and pop outstanding publish request
                    publish_request = self._publish_reqs.pop(msg.request)

                    # create a new publication object
                    publication = Publication(msg.publication)

                    # resolve deferred/future for publishing successfully
                    txaio.resolve(publish_request.on_reply, publication)
                else:
                    raise ProtocolError(
                        "PUBLISHED received for non-pending request ID {0}".
                        format(msg.request))

            elif isinstance(msg, message.Subscribed):

                if msg.request in self._subscribe_reqs:

                    # get and pop outstanding subscribe request
                    request = self._subscribe_reqs.pop(msg.request)

                    # create new handler subscription list for subscription ID if not yet tracked
                    if msg.subscription not in self._subscriptions:
                        self._subscriptions[msg.subscription] = []

                    subscription = Subscription(msg.subscription,
                                                request.topic, self,
                                                request.handler)

                    # add handler to existing subscription
                    self._subscriptions[msg.subscription].append(subscription)

                    # resolve deferred/future for subscribing successfully
                    txaio.resolve(request.on_reply, subscription)
                else:
                    raise ProtocolError(
                        "SUBSCRIBED received for non-pending request ID {0}".
                        format(msg.request))

            elif isinstance(msg, message.Unsubscribed):

                if msg.request in self._unsubscribe_reqs:

                    # get and pop outstanding subscribe request
                    request = self._unsubscribe_reqs.pop(msg.request)

                    # if the subscription still exists, mark as inactive and remove ..
                    if request.subscription_id in self._subscriptions:
                        for subscription in self._subscriptions[
                                request.subscription_id]:
                            subscription.active = False
                        del self._subscriptions[request.subscription_id]

                    # resolve deferred/future for unsubscribing successfully
                    txaio.resolve(request.on_reply, 0)
                else:
                    raise ProtocolError(
                        "UNSUBSCRIBED received for non-pending request ID {0}".
                        format(msg.request))

            elif isinstance(msg, message.Result):

                if msg.request in self._call_reqs:

                    if msg.progress:

                        # progressive result
                        call_request = self._call_reqs[msg.request]
                        if call_request.options.on_progress:
                            kw = msg.kwargs or dict()
                            args = msg.args or tuple()
                            try:
                                # XXX what if on_progress returns a Deferred/Future?
                                call_request.options.on_progress(*args, **kw)
                            except Exception:
                                try:
                                    self.onUserError(
                                        txaio.create_failure(),
                                        "While firing on_progress",
                                    )
                                except:
                                    pass

                        else:
                            # silently ignore progressive results
                            pass

                    else:
                        # final result
                        #
                        call_request = self._call_reqs.pop(msg.request)

                        on_reply = call_request.on_reply

                        if msg.kwargs:
                            if msg.args:
                                res = types.CallResult(*msg.args, **msg.kwargs)
                            else:
                                res = types.CallResult(**msg.kwargs)
                            txaio.resolve(on_reply, res)
                        else:
                            if msg.args:
                                if len(msg.args) > 1:
                                    res = types.CallResult(*msg.args)
                                    txaio.resolve(on_reply, res)
                                else:
                                    txaio.resolve(on_reply, msg.args[0])
                            else:
                                txaio.resolve(on_reply, None)
                else:
                    raise ProtocolError(
                        "RESULT received for non-pending request ID {0}".
                        format(msg.request))

            elif isinstance(msg, message.Invocation):

                if msg.request in self._invocations:

                    raise ProtocolError(
                        "INVOCATION received for request ID {0} already invoked"
                        .format(msg.request))

                else:

                    if msg.registration not in self._registrations:

                        raise ProtocolError(
                            "INVOCATION received for non-registered registration ID {0}"
                            .format(msg.registration))

                    else:
                        registration = self._registrations[msg.registration]
                        endpoint = registration.endpoint

                        if endpoint.obj is not None:
                            invoke_args = (endpoint.obj, )
                        else:
                            invoke_args = tuple()

                        if msg.args:
                            invoke_args = invoke_args + tuple(msg.args)

                        invoke_kwargs = msg.kwargs if msg.kwargs else dict()

                        if endpoint.details_arg:

                            if msg.receive_progress:

                                def progress(*args, **kwargs):
                                    progress_msg = message.Yield(msg.request,
                                                                 args=args,
                                                                 kwargs=kwargs,
                                                                 progress=True)
                                    self._transport.send(progress_msg)
                            else:
                                progress = None

                            invoke_kwargs[
                                endpoint.details_arg] = types.CallDetails(
                                    progress,
                                    caller=msg.caller,
                                    procedure=msg.procedure)

                        on_reply = txaio.as_future(endpoint.fn, *invoke_args,
                                                   **invoke_kwargs)

                        def success(res):
                            del self._invocations[msg.request]

                            if isinstance(res, types.CallResult):
                                reply = message.Yield(msg.request,
                                                      args=res.results,
                                                      kwargs=res.kwresults)
                            else:
                                reply = message.Yield(msg.request, args=[res])

                            try:
                                self._transport.send(reply)
                            except SerializationError as e:
                                # the application-level payload returned from the invoked procedure can't be serialized
                                reply = message.Error(
                                    message.Invocation.MESSAGE_TYPE,
                                    msg.request,
                                    ApplicationError.INVALID_PAYLOAD,
                                    args=[
                                        u'success return value from invoked procedure "{0}" could not be serialized: {1}'
                                        .format(registration.procedure, e)
                                    ])
                                self._transport.send(reply)

                        def error(err):
                            errmsg = txaio.failure_message(err)
                            try:
                                self.onUserError(err, errmsg)
                            except:
                                pass
                            formatted_tb = None
                            if self.traceback_app:
                                formatted_tb = txaio.failure_format_traceback(
                                    err)

                            del self._invocations[msg.request]

                            reply = self._message_from_exception(
                                message.Invocation.MESSAGE_TYPE,
                                msg.request,
                                err.value,
                                formatted_tb,
                            )

                            try:
                                self._transport.send(reply)
                            except SerializationError as e:
                                # the application-level payload returned from the invoked procedure can't be serialized
                                reply = message.Error(
                                    message.Invocation.MESSAGE_TYPE,
                                    msg.request,
                                    ApplicationError.INVALID_PAYLOAD,
                                    args=[
                                        u'error return value from invoked procedure "{0}" could not be serialized: {1}'
                                        .format(registration.procedure, e)
                                    ])
                                self._transport.send(reply)
                            # we have handled the error, so we eat it
                            return None

                        self._invocations[msg.request] = InvocationRequest(
                            msg.request, on_reply)

                        txaio.add_callbacks(on_reply, success, error)

            elif isinstance(msg, message.Interrupt):

                if msg.request not in self._invocations:
                    raise ProtocolError(
                        "INTERRUPT received for non-pending invocation {0}".
                        format(msg.request))
                else:
                    # noinspection PyBroadException
                    try:
                        self._invocations[msg.request].cancel()
                    except Exception:
                        # XXX can .cancel() return a Deferred/Future?
                        try:
                            self.onUserError(
                                txaio.create_failure(),
                                "While cancelling call.",
                            )
                        except:
                            pass
                    finally:
                        del self._invocations[msg.request]

            elif isinstance(msg, message.Registered):

                if msg.request in self._register_reqs:

                    # get and pop outstanding register request
                    request = self._register_reqs.pop(msg.request)

                    # create new registration if not yet tracked
                    if msg.registration not in self._registrations:
                        registration = Registration(self, msg.registration,
                                                    request.procedure,
                                                    request.endpoint)
                        self._registrations[msg.registration] = registration
                    else:
                        raise ProtocolError(
                            "REGISTERED received for already existing registration ID {0}"
                            .format(msg.registration))

                    txaio.resolve(request.on_reply, registration)
                else:
                    raise ProtocolError(
                        "REGISTERED received for non-pending request ID {0}".
                        format(msg.request))

            elif isinstance(msg, message.Unregistered):

                if msg.request in self._unregister_reqs:

                    # get and pop outstanding subscribe request
                    request = self._unregister_reqs.pop(msg.request)

                    # if the registration still exists, mark as inactive and remove ..
                    if request.registration_id in self._registrations:
                        self._registrations[
                            request.registration_id].active = False
                        del self._registrations[request.registration_id]

                    # resolve deferred/future for unregistering successfully
                    txaio.resolve(request.on_reply)
                else:
                    raise ProtocolError(
                        "UNREGISTERED received for non-pending request ID {0}".
                        format(msg.request))

            elif isinstance(msg, message.Error):

                # remove outstanding request and get the reply deferred/future
                on_reply = None

                # ERROR reply to CALL
                if msg.request_type == message.Call.MESSAGE_TYPE and msg.request in self._call_reqs:
                    on_reply = self._call_reqs.pop(msg.request).on_reply

                # ERROR reply to PUBLISH
                elif msg.request_type == message.Publish.MESSAGE_TYPE and msg.request in self._publish_reqs:
                    on_reply = self._publish_reqs.pop(msg.request).on_reply

                # ERROR reply to SUBSCRIBE
                elif msg.request_type == message.Subscribe.MESSAGE_TYPE and msg.request in self._subscribe_reqs:
                    on_reply = self._subscribe_reqs.pop(msg.request).on_reply

                # ERROR reply to UNSUBSCRIBE
                elif msg.request_type == message.Unsubscribe.MESSAGE_TYPE and msg.request in self._unsubscribe_reqs:
                    on_reply = self._unsubscribe_reqs.pop(msg.request).on_reply

                # ERROR reply to REGISTER
                elif msg.request_type == message.Register.MESSAGE_TYPE and msg.request in self._register_reqs:
                    on_reply = self._register_reqs.pop(msg.request).on_reply

                # ERROR reply to UNREGISTER
                elif msg.request_type == message.Unregister.MESSAGE_TYPE and msg.request in self._unregister_reqs:
                    on_reply = self._unregister_reqs.pop(msg.request).on_reply

                if on_reply:
                    txaio.reject(on_reply, self._exception_from_message(msg))
                else:
                    raise ProtocolError(
                        "WampAppSession.onMessage(): ERROR received for non-pending request_type {0} and request ID {1}"
                        .format(msg.request_type, msg.request))

            else:

                raise ProtocolError("Unexpected message {0}".format(
                    msg.__class__))
Example #47
0
 def _cb(arg):
     txaio.resolve(d, arg)
Example #48
0
 def main_success(_):
     self.log.debug("main_success")
     txaio.resolve(done, None)
Example #49
0
 async def on_connect(req):
     v = await foo(num)
     values.append(v)
     txaio.resolve(done, req)
Example #50
0
def cb(value):
    print("Callback:", value)
    return value  # should always return input arg


def eb(fail):
    # fail will implement txaio.IFailedPromise
    print("Errback:", fail)
    # fail.printTraceback()
    return fail  # should always return input arg


f0 = txaio.create_future()
f1 = txaio.create_future()
txaio.add_callbacks(f0, cb, eb)
txaio.add_callbacks(f1, cb, eb)

# ...

txaio.reject(f0, RuntimeError("it failed"))
# or can just "txaio.reject(f0)" if inside an except: block
txaio.resolve(f1, "The answer is: 42")

if txaio.using_asyncio:
    # for twisted, we don't need to enter the event-loop for this
    # simple example (since all results are already available), but
    # you'd simply use reactor.run()/.stop() or task.react() as normal
    import asyncio
    asyncio.get_event_loop().run_until_complete(f1)
 def ok(_):
     txaio.resolve(d, None)
Example #52
0
 def session_done(x):
     txaio.resolve(self._done_f, None)