Пример #1
0
def test_use_asyncio(framework_aio):
    pytest.importorskip('asyncio')

    import txaio
    txaio.use_asyncio()
    assert txaio.using_asyncio
    assert not txaio.using_twisted
Пример #2
0
 def __init__(self, url, realm, session_factory):
     self._url = url
     self._realm = realm
     self._loop = asyncio.get_event_loop()
     self._factory = session_factory
     txaio.use_asyncio()
     txaio.config.loop = self._loop
Пример #3
0
async def test_04_rejoin_realm(servicefactory, event_loop):

    # in this case, autobahn requires explicit configuration of the loop via txaio
    # alternatively, use the regular loop (in some cases may need to init txaio even then)

    import txaio
    txaio.use_asyncio()
    txaio.config.loop = event_loop

    server = servicefactory()
    server.set_loop(event_loop)

    async with CrossbarRouter() as cb:
        print("----- router starting, waiting for connect: -------")
        await asyncio.sleep(2, loop=event_loop)
        await server.start()

    print("------- router stopped, connection lost: -------")

    await asyncio.sleep(1, loop=event_loop)

    async with CrossbarRouter() as cb:
        print("------ router starting again, waiting for reconnect: -------")
        await asyncio.sleep(2, loop=event_loop)
        await server.stop()

    await asyncio.sleep(1, loop=event_loop)
Пример #4
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        (transport, protocol) = loop.run_until_complete(coro)
        loop.add_signal_handler(signal.SIGTERM, loop.stop)

        # 4) now enter the asyncio event loop
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass
        # give Goodbye message a chance to go through, if we still
        # have an active session
        if protocol._session:
            loop.run_until_complete(protocol._session.leave())
        loop.close()
Пример #5
0
 def __init__(self, handler, proto_id, auth_strategy, loop):
     txaio.use_asyncio()
     websocket.WebSocketServerProtocol.__init__(self)
     self._handler = handler
     self.proto_id = proto_id
     self._auth_strategy = auth_strategy
     self._loop = loop
     self._authentified = False
     self._auth_app = None
     self._deauth_handle = None
Пример #6
0
 def __init__(self, handler, proto_id, auth_strategy, loop):
     txaio.use_asyncio()
     websocket.WebSocketServerProtocol.__init__(self)
     self._handler = handler
     self.proto_id = proto_id
     self._auth_strategy = auth_strategy
     self._loop = loop
     self._authentified = False
     self._auth_app = None
     self._deauth_handle = None
Пример #7
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        (transport, protocol) = loop.run_until_complete(coro)
        loop.add_signal_handler(signal.SIGTERM, loop.stop)

        # 4) now enter the asyncio event loop
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass
        loop.run_until_complete(protocol._session.leave())
        loop.close()
Пример #8
0
    def __init__(self, dbpath=None, maxsize=10485760, readonly=False, sync=True, open=True, log=None):
        """

        :param dbpath: LMDB database path: a directory with (at least) 2 files, a ``data.mdb`` and a ``lock.mdb``.
            If no database exists at the given path, create a new one.
        :type dbpath: str

        :param maxsize: Database size limit in bytes, with a default of 1MB.
        :type maxsize: int

        :param read_only: Open database read-only. When ``True``, deny any modifying database operations.
            Note that the LMDB lock file (``lock.mdb``) still needs to be written (by readers also),
            and hence at the filesystem level, a LMDB database directory must be writable.
        :type read_only: bool

        :param sync: Open database with sync on commit.
        :type sync: bool
        """
        assert dbpath is None or type(dbpath) == str
        assert type(maxsize) == int
        assert type(readonly) == bool
        assert type(sync) == bool

        if log:
            self.log = log
        else:
            if not txaio._explicit_framework:
                txaio.use_asyncio()
            self.log = txaio.make_logger()

        if dbpath:
            self._is_temp = False
            self._dbpath = dbpath
        else:
            self._is_temp = True
            self._tempdir = tempfile.TemporaryDirectory()
            self._dbpath = self._tempdir.name

        self._maxsize = maxsize
        self._readonly = readonly
        self._sync = sync

        self._slots = None
        self._slots_by_index = None

        # in a context manager environment we initialize with LMDB handle
        # when we enter the actual temporary, managed context ..
        self._env = None

        # in a direct run environment, we immediately open LMDB
        if open:
            self.__enter__()
Пример #9
0
    def run(self, make):
        """
        Run the application component.
        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        def _create_app_session():
            cfg = ComponentConfig(self._realm, self._extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                asyncio.get_event_loop().stop()
                raise e
            else:
                session.debug_app = self._debug_app
                return session

        self._transport_factory = WampWebSocketClientFactory(
            _create_app_session, url=self._url, serializers=self._serializers)

        if self._auto_ping_interval is not None and self._auto_ping_timeout is not None:
            self._transport_factory.setProtocolOptions(
                openHandshakeTimeout=self._open_handshake_timeout,
                autoPingInterval=self._auto_ping_interval,
                autoPingTimeout=self._auto_ping_timeout)

        txaio.use_asyncio()
        txaio.config.loop = self._loop

        asyncio. async (self._connect(), loop=self._loop)

        try:
            self._loop.add_signal_handler(signal.SIGTERM, self.stop)
        except NotImplementedError:
            # Ignore if not implemented. Means this program is running in windows.
            pass

        try:
            self._loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass

        self._closing = True

        if self._active_protocol and self._active_protocol._session:
            self._loop.run_until_complete(
                self._active_protocol._session.leave())
        self._loop.close()
Пример #10
0
    def run(self):
        try:
            asyncio.set_event_loop(self._loop)

            txaio.use_asyncio()
            txaio.config.loop = self._loop

            # Info is too verbose, use error by default
            # TODO: Make logging level for autobahn configurable
            txaio.start_logging(level='error')

            # create a WAMP-over-WebSocket transport client factory
            transport_factory = WampWebSocketClientFactory(
                lambda: self._akcomponent_factory(self._decoupler, self.
                                                  _callback_executor, self.
                                                  _allow_exception),
                url=self._url)

            # Basic settings with most features disabled
            transport_factory.setProtocolOptions(failByDrop=False,
                                                 openHandshakeTimeout=5.,
                                                 closeHandshakeTimeout=1.)

            isSecure, host, port, _, _, _ = parse_ws_url(self._url)
            transport, protocol = self._loop.run_until_complete(
                self._loop.create_connection(transport_factory,
                                             host,
                                             port,
                                             ssl=isSecure))

            try:
                self._loop.run_forever()
            except KeyboardInterrupt:
                # wait until we send Goodbye if user hit ctrl-c
                # (done outside this except so SIGTERM gets the same handling)
                pass

            # give Goodbye message a chance to go through, if we still
            # have an active session
            if protocol._session:
                self._loop.run_until_complete(protocol._session.leave())

            self._loop.close()
        except Exception as e:
            errorStr = pformat(e)
            stderr.write(errorStr + "\n")

            # Wake the caller, this thread will terminate right after so the
            # error can be detected by checking if the thread is alive
            self._decoupler.set_joined()

        self._decoupler.unblock_caller()
Пример #11
0
    async def start(self, ctx: Context):
        # Autobahn uses txaio to bridge the API gap between asyncio and Twisted so we need to set
        # it up for asyncio here
        txaio.use_asyncio()
        txaio.config.loop = get_event_loop()

        for resource_name, context_attr, client in self.clients:
            await client.start(ctx)
            ctx.publish_resource(client, resource_name, context_attr)
            logger.info(
                'Configured WAMP client (%s / ctx.%s; host=%s; port=%d; realm=%s)',
                resource_name, context_attr, client.host, client.port,
                client.realm)
Пример #12
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        loop.run_until_complete(coro)

        # 4) now enter the asyncio event loop
        loop.run_forever()
        loop.close()
Пример #13
0
    def run(self, make, app_cfg=None):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        self.loop = self.loop or asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = self.loop

        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            session = make(cfg, app_cfg=app_cfg, loop=self.loop)
            session.debug_app = self.debug_app
            return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create,
            url=self.url,
            serializers=self.serializers,
            debug=self.debug,
            debug_wamp=self.debug_wamp,
            loop=self.loop)

        # 3) start the client
        coro = self.loop.create_connection(transport_factory,
                                           host,
                                           port,
                                           ssl=ssl)
        (self.transport, self.protocol) = self.loop.run_until_complete(coro)
Пример #14
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create,
            url=self.url,
            serializers=self.serializers,
            debug=self.debug,
            debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory,
                                      host,
                                      port,
                                      ssl=isSecure)
        loop.run_until_complete(coro)

        # 4) now enter the asyncio event loop
        loop.run_forever()
        loop.close()
Пример #15
0
async def test_03_asyncio_join_realm(servicefactory, event_loop,
                                     crossbar_router_running):

    # in this case, autobahn requires explicit configuration of the loop via txaio
    # alternatively, use the regular loop (in some cases may need to init txaio even then)

    import txaio
    txaio.use_asyncio()
    txaio.config.loop = event_loop

    server = servicefactory()
    server.set_loop(event_loop)
    await asyncio.sleep(1, loop=event_loop)
    print("--- waiting for server start() ---")
    await server.start()
    await asyncio.sleep(2, loop=event_loop)
    print("--- waiting for server stop() ---")
    await server.stop()
Пример #16
0
    def run(self, make):
        """
        Run the application component.
        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        def _create_app_session():
            cfg = ComponentConfig(self._realm, self._extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                asyncio.get_event_loop().stop()
                raise e
            else:
                session.debug_app = self._debug_app
                return session

        self._transport_factory = WampWebSocketClientFactory(_create_app_session, url=self._url, serializers=self._serializers)

        if self._auto_ping_interval is not None and self._auto_ping_timeout is not None:
            self._transport_factory.setProtocolOptions(autoPingInterval=self._auto_ping_interval, autoPingTimeout=self._auto_ping_timeout)

        txaio.use_asyncio()
        txaio.config.loop = self._loop

        asyncio.async(self._connect(), loop=self._loop)
        self._loop.add_signal_handler(signal.SIGTERM, self.stop)

        try:
            self._loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass

        self._closing = True

        if self._active_protocol and self._active_protocol._session:
            self._loop.run_until_complete(self._active_protocol._session.leave())
        self._loop.close()
Пример #17
0
    async def start(self, ctx: Context):
        # Autobahn uses txaio to bridge the API gap between asyncio and Twisted so we need to set
        # it up for asyncio here
        txaio.use_asyncio()
        txaio.config.loop = ctx.loop

        ctx.add_resource(WAMPExtrasProvider(), 'wamp', types=[ExtrasProvider])

        for resource_name, context_attr, client in self.clients:
            await client.start(ctx)
            ctx.add_resource(client, resource_name, context_attr)
            logger.info('Configured WAMP client (%s / ctx.%s; host=%s; port=%d; realm=%s)',
                        resource_name, context_attr, client.host, client.port, client.realm)

        await yield_()

        for resource_name, context_attr, client in self.clients:
            await client.stop()
            logger.info('Shut down WAMP client (%s)', resource_name)
Пример #18
0
    def run(self, make):
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parse_url(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers)
        # transport_factory.setProtocolOptions(failByDrop=False, openHandshakeTimeout=90, closeHandshakeTimeout=5)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        (transport, protocol) = loop.run_until_complete(coro)

        try:
            loop.add_signal_handler(signal.SIGTERM, loop.stop)
        except NotImplementedError:
            # signals are not available on Windows
            pass
Пример #19
0
def main():
    prefix = 'opendna.autobahn.repl'
    dest__class = {
        'connection_manager': f'{prefix}.connections.ConnectionManager',
        'connection': f'{prefix}.connections.Connection',
        'session': f'{prefix}.sessions.Session',
        'call_manager': f'{prefix}.rpc.CallManager',
        'call': f'{prefix}.rpc.Call',
        'invocation': f'{prefix}.rpc.Invocation',
        'registration_manager': f'{prefix}.rpc.RegistrationManager',
        'registration': f'{prefix}.rpc.Registration',
        'publisher_manager': f'{prefix}.pubsub.PublisherManager',
        'publisher': f'{prefix}.pubsub.Publisher',
        'publication': f'{prefix}.pubsub.Publication',
        'subscription_manager': f'{prefix}.pubsub.SubscriptionManager',
        'subscription': f'{prefix}.pubsub.Subscription',
        'application_runner': 'autobahn.asyncio.wamp.ApplicationRunner',
        'application_session': f'{prefix}.wamp.REPLApplicationSession'
    }
    parser = ArgumentParser(
        description='Python REPL for interacting with Crossbar')
    for dest, class_ in dest__class.items():
        parser.add_argument(f'--{dest.replace("_", "-")}',
                            default=class_,
                            dest=dest)
    parser.add_argument('--history-file',
                        dest='history_file',
                        default=DEFAULT_HISTORY_FILE)
    parser.add_argument('--config-file',
                        dest='config_file',
                        default=DEFAULT_CONFIG_FILE)
    args = parser.parse_args()
    environ.update({
        key: value
        for key, value in vars(args).items()
        if key in dest__class or key in {'history_file', 'config_file'}
    })
    loop = asyncio.get_event_loop()
    txaio.use_asyncio()
    txaio.config.loop = loop
    loop.run_until_complete(start_repl(loop))
    loop.stop()
Пример #20
0
def test_01_join_realm(servicefactory, event_loop, crossbar_router_running):

    # in this case, autobahn requires explicit configuration of the loop via txaio
    # alternatively, use the regular loop (in some cases may need to init txaio even then)

    import txaio
    txaio.use_asyncio()
    txaio.config.loop = event_loop

    loop = event_loop

    server = servicefactory()
    server.set_loop(loop)
    time.sleep(1)
    print("--- running server start() ---")
    loop.run_until_complete(server.start())
    time.sleep(1)
    print("--- running server stop() ---")
    loop.run_until_complete(server.stop())
    remaining = asyncio.Task.all_tasks(loop=loop)
    loop.run_until_complete(asyncio.gather(*remaining))
Пример #21
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=isSecure)
        loop.run_until_complete(coro)

        # 4) now enter the asyncio event loop
        loop.run_forever()
        loop.close()
Пример #22
0
    def _start(self):
        if self.session:
            return

        import asyncio
        import txaio
        txaio.use_asyncio()
        txaio.config.loop = self.loop = asyncio.get_event_loop()

        from autobahn.wamp import protocol
        from autobahn.wamp.types import ComponentConfig
        from autobahn.websocket.util import parse_url
        from autobahn.asyncio.websocket import WampWebSocketClientFactory

        from ..remote.client import ClientSession

        @asyncio.coroutine
        def _connected(session):
            self.ready.set()

        def create():
            cfg = ComponentConfig(self.realm, {
                'loop': self.loop,
                'func': _connected,
            })
            self.session = ClientSession(cfg)
            return self.session

        transport_factory = WampWebSocketClientFactory(create, url=self.url)
        _, host, port, _, _, _ = parse_url(self.url)

        self.ready = asyncio.Event()
        coro = self.loop.create_connection(transport_factory, host, port)
        (transport, protocol) = self.loop.run_until_complete(coro)
        print(transport, protocol)
        self.loop.run_until_complete(self.ready.wait())
Пример #23
0
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################

import sys
import logging

import txaio
txaio.use_asyncio()


# some library you use is using txaio logging stuff
class Library(object):
    log = txaio.make_logger()

    def something(self):
        self.log.info("info log from library foo={foo}", foo='bar')
        self.log.debug("debug information")
        self.log.error("An error in the library num={num}", num=42)


lib = Library()
print("logging not started")
Пример #24
0
from __future__ import absolute_import
import signal

import six

try:
    import asyncio
except ImportError:
    # Trollius >= 0.3 was renamed to asyncio
    # noinspection PyUnresolvedReferences
    import trollius as asyncio

import txaio

txaio.use_asyncio()  # noqa

from autobahn.util import public
from autobahn.wamp import protocol
from autobahn.wamp.types import ComponentConfig

from autobahn.websocket.util import parse_url as parse_ws_url
from autobahn.rawsocket.util import parse_url as parse_rs_url

from autobahn.asyncio.websocket import WampWebSocketClientFactory
from autobahn.asyncio.rawsocket import WampRawSocketClientFactory

from autobahn.websocket.compress import PerMessageDeflateOffer, \
    PerMessageDeflateResponse, PerMessageDeflateResponseAccept

__all__ = ('ApplicationSession', 'ApplicationSessionFactory',
Пример #25
0
    def run(self, make, start_loop=True, log_level='info'):
        """
        Run the application component. Under the hood, this runs the event
        loop (unless `start_loop=False` is passed) so won't return
        until the program is done.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_loop: When ``True`` (the default) this method
            start a new asyncio loop.
        :type start_loop: bool

        :returns: None is returned, unless you specify
            `start_loop=False` in which case the coroutine from calling
            `loop.create_connection()` is returned. This will yield the
            (transport, protocol) pair.
        """
        if callable(make):

            def create():
                cfg = ComponentConfig(self.realm, self.extra)
                try:
                    session = make(cfg)
                except Exception as e:
                    self.log.error(
                        'ApplicationSession could not be instantiated: {}'.
                        format(e))
                    loop = asyncio.get_event_loop()
                    if loop.is_running():
                        loop.stop()
                    raise
                else:
                    return session
        else:
            create = make

        if self.url.startswith(u'rs'):
            # try to parse RawSocket URL ..
            isSecure, host, port = parse_rs_url(self.url)

            # use the first configured serializer if any (which means, auto-choose "best")
            serializer = self.serializers[0] if self.serializers else None

            # create a WAMP-over-RawSocket transport client factory
            transport_factory = WampRawSocketClientFactory(
                create, serializer=serializer)

        else:
            # try to parse WebSocket URL ..
            isSecure, host, port, resource, path, params = parse_ws_url(
                self.url)

            # create a WAMP-over-WebSocket transport client factory
            transport_factory = WampWebSocketClientFactory(
                create,
                url=self.url,
                serializers=self.serializers,
                proxy=self.proxy,
                headers=self.headers)

            # client WebSocket settings - similar to:
            # - http://crossbar.io/docs/WebSocket-Compression/#production-settings
            # - http://crossbar.io/docs/WebSocket-Options/#production-settings

            # The permessage-deflate extensions offered to the server ..
            offers = [PerMessageDeflateOffer()]

            # Function to accept permessage_delate responses from the server ..
            def accept(response):
                if isinstance(response, PerMessageDeflateResponse):
                    return PerMessageDeflateResponseAccept(response)

            # set WebSocket options for all client connections
            transport_factory.setProtocolOptions(
                maxFramePayloadSize=1048576,
                maxMessagePayloadSize=1048576,
                autoFragmentSize=65536,
                failByDrop=False,
                openHandshakeTimeout=2.5,
                closeHandshakeTimeout=1.,
                tcpNoDelay=True,
                autoPingInterval=10.,
                autoPingTimeout=5.,
                autoPingSize=4,
                perMessageCompressionOffers=offers,
                perMessageCompressionAccept=accept)
        # SSL context for client connection
        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # start the client connection
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)

        # start a asyncio loop
        if not start_loop:
            return coro
        else:
            (transport, protocol) = loop.run_until_complete(coro)

            # start logging
            txaio.start_logging(level=log_level)

            try:
                loop.add_signal_handler(signal.SIGTERM, loop.stop)
            except NotImplementedError:
                # signals are not available on Windows
                pass

            # 4) now enter the asyncio event loop
            try:
                loop.run_forever()
            except KeyboardInterrupt:
                # wait until we send Goodbye if user hit ctrl-c
                # (done outside this except so SIGTERM gets the same handling)
                pass

            # give Goodbye message a chance to go through, if we still
            # have an active session
            if protocol._session:
                loop.run_until_complete(protocol._session.leave())

            loop.close()
Пример #26
0
    def run(self, make, logging_level='info'):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception:
                self.log.failure("App session could not be created! ")
                asyncio.get_event_loop().stop()
            else:
                return session

        parsed_url = urlparse(self.url)

        if parsed_url.scheme == 'tcp':
            is_unix = False
            if not parsed_url.hostname or not parsed_url.port:
                raise ValueError('Host and port is required in URL')
        elif parsed_url.scheme == 'unix' or parsed_url.scheme == '':
            is_unix = True
            if not parsed_url.path:
                raise ValueError('Path to unix socket must be in URL')

        transport_factory = WampRawSocketClientFactory(create, serializer=self.serializer)

        loop = asyncio.get_event_loop()
        if logging_level == 'debug':
            loop.set_debug(True)
        txaio.use_asyncio()
        txaio.config.loop = loop

        try:
            loop.add_signal_handler(signal.SIGTERM, loop.stop)
        except NotImplementedError:
            # signals are not available on Windows
            pass

        def handle_error(loop, context):
            self.log.error('Application Error: {err}', err=context)
            loop.stop()

        loop.set_exception_handler(handle_error)

        if is_unix:
            coro = loop.create_unix_connection(transport_factory, parsed_url.path)
        else:
            coro = loop.create_connection(transport_factory, parsed_url.hostname, parsed_url.port)
        (_transport, protocol) = loop.run_until_complete(coro)

        txaio.start_logging(level=logging_level)  # @UndefinedVariable

        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        self.log.debug('Left main loop waiting for completion')
        # give Goodbye message a chance to go through, if we still
        # have an active session
        # it's not working now - because protocol is_closed must return Future
        if protocol._session:
            loop.run_until_complete(protocol._session.leave())

        loop.close()
Пример #27
0
import six

from autobahn.wamp import protocol
from autobahn.wamp.types import ComponentConfig
from autobahn.websocket.util import parse_url
from autobahn.asyncio.websocket import WampWebSocketClientFactory

try:
    import asyncio
except ImportError:
    # Trollius >= 0.3 was renamed to asyncio
    # noinspection PyUnresolvedReferences
    import trollius as asyncio

import txaio
txaio.use_asyncio()

__all__ = (
    'ApplicationSession',
    'ApplicationSessionFactory',
    'ApplicationRunner'
)


class ApplicationSession(protocol.ApplicationSession):
    """
    WAMP application session for asyncio-based applications.
    """


class ApplicationSessionFactory(protocol.ApplicationSessionFactory):
Пример #28
0
    def run(self, make, start_loop=True, log_level='info'):
        """
        Run the application component. Under the hood, this runs the event
        loop (unless `start_loop=False` is passed) so won't return
        until the program is done.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_loop: When ``True`` (the default) this method
            start a new asyncio loop.
        :type start_loop: bool

        :returns: None is returned, unless you specify
            `start_loop=False` in which case the coroutine from calling
            `loop.create_connection()` is returned. This will yield the
            (transport, protocol) pair.
        """
        if callable(make):
            def create():
                cfg = ComponentConfig(self.realm, self.extra)
                try:
                    session = make(cfg)
                except Exception as e:
                    self.log.error('ApplicationSession could not be instantiated: {}'.format(e))
                    loop = asyncio.get_event_loop()
                    if loop.is_running():
                        loop.stop()
                    raise
                else:
                    return session
        else:
            create = make

        if self.url.startswith(u'rs'):
            # try to parse RawSocket URL ..
            isSecure, host, port = parse_rs_url(self.url)

            # use the first configured serializer if any (which means, auto-choose "best")
            serializer = self.serializers[0] if self.serializers else None

            # create a WAMP-over-RawSocket transport client factory
            transport_factory = WampRawSocketClientFactory(create, serializer=serializer)

        else:
            # try to parse WebSocket URL ..
            isSecure, host, port, resource, path, params = parse_ws_url(self.url)

            # create a WAMP-over-WebSocket transport client factory
            transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers, proxy=self.proxy, headers=self.headers)

            # client WebSocket settings - similar to:
            # - http://crossbar.io/docs/WebSocket-Compression/#production-settings
            # - http://crossbar.io/docs/WebSocket-Options/#production-settings

            # The permessage-deflate extensions offered to the server ..
            offers = [PerMessageDeflateOffer()]

            # Function to accept permessage_delate responses from the server ..
            def accept(response):
                if isinstance(response, PerMessageDeflateResponse):
                    return PerMessageDeflateResponseAccept(response)

            # set WebSocket options for all client connections
            transport_factory.setProtocolOptions(maxFramePayloadSize=1048576,
                                                 maxMessagePayloadSize=1048576,
                                                 autoFragmentSize=65536,
                                                 failByDrop=False,
                                                 openHandshakeTimeout=2.5,
                                                 closeHandshakeTimeout=1.,
                                                 tcpNoDelay=True,
                                                 autoPingInterval=10.,
                                                 autoPingTimeout=5.,
                                                 autoPingSize=4,
                                                 perMessageCompressionOffers=offers,
                                                 perMessageCompressionAccept=accept)
        # SSL context for client connection
        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # start the client connection
        loop = asyncio.get_event_loop()
        if loop.is_closed() and start_loop:
            asyncio.set_event_loop(asyncio.new_event_loop())
            loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)

        # start a asyncio loop
        if not start_loop:
            return coro
        else:
            (transport, protocol) = loop.run_until_complete(coro)

            # start logging
            txaio.start_logging(level=log_level)

            try:
                loop.add_signal_handler(signal.SIGTERM, loop.stop)
            except NotImplementedError:
                # signals are not available on Windows
                pass

            # 4) now enter the asyncio event loop
            try:
                loop.run_forever()
            except KeyboardInterrupt:
                # wait until we send Goodbye if user hit ctrl-c
                # (done outside this except so SIGTERM gets the same handling)
                pass

            # give Goodbye message a chance to go through, if we still
            # have an active session
            if protocol._session:
                loop.run_until_complete(protocol._session.leave())

            loop.close()
Пример #29
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                self.log.error(
                    'ApplicationSession could not be instantiated: {}'.format(
                        e))
                loop = asyncio.get_event_loop()
                if loop.is_running():
                    loop.stop()
                raise
            else:
                return session

        isSecure, host, port, resource, path, params = parse_url(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create, url=self.url, serializers=self.serializers)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        (transport, protocol) = loop.run_until_complete(coro)

        # start logging
        txaio.start_logging(level='info')

        try:
            loop.add_signal_handler(signal.SIGTERM, loop.stop)
        except NotImplementedError:
            # signals are not available on Windows
            pass

        # 4) now enter the asyncio event loop
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass

        # give Goodbye message a chance to go through, if we still
        # have an active session
        if protocol._session:
            loop.run_until_complete(protocol._session.leave())

        loop.close()
Пример #30
0
###############################################################################

from __future__ import absolute_import
import signal

import six

try:
    import asyncio
except ImportError:
    # Trollius >= 0.3 was renamed to asyncio
    # noinspection PyUnresolvedReferences
    import trollius as asyncio

import txaio
txaio.use_asyncio()  # noqa

from autobahn.util import public
from autobahn.wamp import protocol
from autobahn.wamp.types import ComponentConfig

from autobahn.websocket.util import parse_url as parse_ws_url
from autobahn.rawsocket.util import parse_url as parse_rs_url

from autobahn.asyncio.websocket import WampWebSocketClientFactory
from autobahn.asyncio.rawsocket import WampRawSocketClientFactory

from autobahn.websocket.compress import PerMessageDeflateOffer, \
    PerMessageDeflateResponse, PerMessageDeflateResponseAccept

__all__ = (
def run():
    parser = RunnerArgumentParser()
    parser.add_argument(
        '-c',
        '--component',
        action='append',
        dest='components',
        required=True,
        help=
        'Fully-qualified path to a Component class. Can be used multiple times'
    )
    parser.add_argument(
        '-n',
        '--necromancy',
        action='store_true',
        default=False,
        help=
        'Enable necromancy. Attempts to revive Components whose connection to the WAMP router has failed'
    )
    parser.add_argument(
        '--necromancy-sleep',
        default=10,
        type=int,
        help='Configure sleep-time between transport death checks')
    args = parser.parse_args()
    extras = {}
    serializers = None
    if args.extra_file is not None:
        extras = json.load(open(args.extra_file))
    if args.serializers is not None:
        serializers = [
            get_class(serializer) for serializer in args.serializers
        ]
    components__runners = [
        (get_class(component),
         ApplicationRunner(extra=extras.get(component),
                           serializers=serializers,
                           **{
                               key: value
                               for key, value in vars(args).items()
                               if key not in ('components', 'log_level',
                                              'extra_file', 'serializers',
                                              'necromancy', 'necromancy_sleep')
                           })) for component in args.components
    ]
    loop = asyncio.get_event_loop()
    txaio.use_asyncio()
    txaio.config.loop = loop
    coros = [
        runner.run(component, start_loop=False, log_level=args.log_level)
        for component, runner in components__runners
    ]
    results = loop.run_until_complete(asyncio.gather(*coros))
    txaio.start_logging(level=args.log_level)
    logger = logging.getLogger('autobahn-python-runners')

    if args.necromancy:
        logging.info('Necromancy enabled')

        @asyncio.coroutine
        def necromancy_check():
            nonlocal results, components__runners
            while True:
                yield from asyncio.sleep(args.necromancy_sleep)
                logger.info('Checking for dead transports...')
                data = enumerate(zip(components__runners, results))
                for index, ((component, runner), (transport,
                                                  protocol)) in data:
                    if transport.is_closing() and not protocol._session:
                        logger.info(
                            'Dead transport detected. Attempting to raise the dead...'
                        )
                        results[index] = yield from runner.run(
                            component,
                            start_loop=False,
                            log_level=args.log_level)

        asyncio.ensure_future(necromancy_check(), loop=loop)

    try:
        loop.add_signal_handler(signal.SIGTERM, loop.stop)
    except NotImplementedError:
        # signals are not available on Windows
        pass

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        # wait until we send Goodbye if user hit ctrl-c
        # (done outside this except so SIGTERM gets the same handling)
        pass

    coros = [
        loop.run_until_complete(protocol._session.leave())
        for tranport, protocol in results if protocol._session
    ]

    loop.close()
Пример #32
0
def setup_txaio(event_loop):
    txaio.use_asyncio()
    txaio.config.loop = event_loop
Пример #33
0
def setup_txaio(event_loop):
    txaio.use_asyncio()
    txaio.config.loop = event_loop
Пример #34
0
    def run(self, make, logging_level='info'):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception:
                self.log.failure("App session could not be created! ")
                asyncio.get_event_loop().stop()
            else:
                return session

        parsed_url = urlparse(self.url)

        if parsed_url.scheme == 'tcp':
            is_unix = False
            if not parsed_url.hostname or not parsed_url.port:
                raise ValueError('Host and port is required in URL')
        elif parsed_url.scheme == 'unix' or parsed_url.scheme == '':
            is_unix = True
            if not parsed_url.path:
                raise ValueError('Path to unix socket must be in URL')

        transport_factory = WampRawSocketClientFactory(
            create, serializer=self.serializer)

        loop = asyncio.get_event_loop()
        if logging_level == 'debug':
            loop.set_debug(True)
        txaio.use_asyncio()
        txaio.config.loop = loop

        try:
            loop.add_signal_handler(signal.SIGTERM, loop.stop)
        except NotImplementedError:
            # signals are not available on Windows
            pass

        def handle_error(loop, context):
            self.log.error('Application Error: {err}', err=context)
            loop.stop()

        loop.set_exception_handler(handle_error)

        if is_unix:
            coro = loop.create_unix_connection(transport_factory,
                                               parsed_url.path)
        else:
            coro = loop.create_connection(transport_factory,
                                          parsed_url.hostname, parsed_url.port)
        (_transport, protocol) = loop.run_until_complete(coro)

        txaio.start_logging(level=logging_level)  # @UndefinedVariable

        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        self.log.debug('Left main loop waiting for completion')
        # give Goodbye message a chance to go through, if we still
        # have an active session
        # it's not working now - because protocol is_closed must return Future
        if protocol._session:
            loop.run_until_complete(protocol._session.leave())

        loop.close()