def simple_concurrency():
    """ This is an example where we set two different registered URIs

        - a URI that will have a the default concurrency limit that lets
            it run only one at a time. We set a default global concurrency
            limit to "1" when instantiating the client object. This global
            concurrency limit is shared between all registrations and subscriptions.
            If a more granular approach is required, have a look at this file's
            second example.

        - a second URI that will not be limited concurrency-wise. This is
            achieved by setting the concurrency queue that it uses to "unlimited"

    """
    client = swampyer.WAMPClient(
                    url="ws://localhost:8282/ws",
                    uri_base="com.example.wamp.api",
                    concurrency_max=1 # By default all registrations, subscriptions can
                                      # run single threaded (and they get queued) globally
                ).start()

    def hello_world(*args, **kwargs):
        print("Received Args:{} Kwargs:{}".format(args,kwargs))
        return "Hello there!"

    # This URI uses the global concurrency limit
    client.register("hello", hello_world)

    # This one uses the unlimited queue (so no concurrency limit at all)
    client.register("hello2", hello_world, concurrency_queue="unlimited")
Exemple #2
0
    def test_import(self):
        ex = None
        try:
            # Launch Crossbar

            import swampyer
            client = swampyer.WAMPClient(
                            #url="ws://localhost:8282/ws"
                            url="wss://demo.crossbar.io/ws",
                            realm="realm1",
                        ).start()

            time.sleep(1)

        except swampyer.exceptions.ExAbort as expectedException:
            pass
        except Exception as ex:
            pass
        self.assertIsNone(ex,msg="Swampyer connect failed because {}".format(ex))
Exemple #3
0
#!/bin/bash

from __future__ import print_function

import swampyer

import time
import sys
import logging

logging.basicConfig(stream=sys.stdout, level=1)

try:
    client = swampyer.WAMPClient(
        url="ws://localhost:8282/ws",
        uri_base="com.example.wamp.api",
    ).start()

    def hello_world(*args, **kwargs):
        print("Received Args:{} Kwargs:{}".format(args, kwargs))
        return "Hello there!"

    client.register("hello", hello_world)

    # Run for 1 minute then quiet
    time.sleep(60)

    # Print some basic stats on what was done
    #
    # client.stats() returns a dict of:
    #
Exemple #4
0
#!/bin/bash

from __future__ import print_function

import websocket
import swampyer
import sys
import logging

# Produce lots of data
# websocket.enableTrace(True)

# We want to see the protocol information
# being exchanged
logging.basicConfig(stream=sys.stdout, level=1)

try:
    client = swampyer.WAMPClient(
        url="ws://localhost:8282/ws"
        #url="wss://demo.crossbar.io/ws",
        #realm="crossbardemo",
    ).start()
    print(client)
except swampyer.SwampyException as ex:
    print("Whoops, something went wrong: {}".format(ex))
Exemple #5
0
- https://crossbar.io/docs/RawSocket-Transport/?highlight=transport#connecting-transports
- https://crossbar.io/docs/Transport-Endpoints/#unix-domain-connecting-endpoints

See the tests/test_server/.crossbar/config.yaml file for an example
configuration for the crossbar server.
"""

from __future__ import print_function

import websocket
import swampyer
import sys
import logging

# Produce lots of data
# websocket.enableTrace(True)

# We want to see the protocol information
# being exchanged
logging.basicConfig(stream=sys.stdout, level=1)

try:
    client = swampyer.WAMPClient(
                    url="unix:///tmp/nexus.socket",
                ).start()
    print(client)
except swampyer.SwampyException as ex:
    print("Whoops, something went wrong: {}".format(ex))


def targetted_concurrency():
    """ This is an example where we set multiple URIs with differing concurrency policies

        1. a URI that will have a the default concurrency limit that lets
            it run only one at a time. We set a default global concurrency
            limit to "1" when instantiating the client object. This global
            concurrency limit is shared between all registrations and subscriptions.

        2. a URI that will not be limited to a higher value of 5. This is achieved
            by providing a hash to the `concurrency_max` argument at client instantiation.
            All registrations/subscriptions sharing a queue_name will also share concurrency.
            By also setting `queue_max` to 100, if there are 100 waiting requests, the 101st
            and so on will be rejected outright. If the request is an INVOKE message, then it
            will send an ERROR response back so that the client who requested the call will
            know they were rejected.

        3. a URI that will not be limited concurrency-wise. This is
            achieved by setting the concurrency queue that it uses to "unlimited"

        4. a URI that will use the default concurrency maximum (of 1). When providing
            config, if no default keys are set, it will use the `default` queue's settings.

        The code will also demonstrate how to change the concurrency limits dynamically
        
    """
    client = swampyer.WAMPClient(
                    url="ws://localhost:8282/ws",
                    uri_base="com.example.wamp.api",
                    concurrency_configs={
                      'default': {
                          'concurrency_max': 1,
                      }
                      'new-queue': {
                          'concurrency_max': 5,
                          'queue_max': 100,
                      }
                      'use_default': {
                      }
                    },
                ).start()

    def hello_world(*args, **kwargs):
        print("Received Args:{} Kwargs:{}".format(args,kwargs))
        return "Hello there!"

    # This URI uses the global concurrency limit. By default the "default"
    # concurrency_queue is implied
    client.register("hello", hello_world)

    # This one uses the second queue named "new-queue"
    client.register("hello2", hello_world, concurrency_queue="new-queue")

    # The unlimited queue also exists and is created automatically
    client.register("hello3", hello_world, concurrency_queue="unlimited")

    # The 'use_default' queue because it is set to None will use the default
    # settings of '1'
    client.register("hello4", hello_world, concurrency_queue="use_default")

    # Change the concurrency limit for `new-queue` from 5 to 50
    # If limit goes up,
    client.concurrency_queue_get('new-queue').configure(concurrency_max=5)

    # By default supplying names that have not previously been defined
    # in `concurrency_max` will throw the ExNotImplemented error
    try:
        client.register("hello5", hello_world, concurrency_queue="nonexisting")
    except NotImplementedError:
        pass

    # However, if the key `concurrency_strict_naming` is set to false. It will
    # create a new queue based upon the default value
    client.configure(concurrency_strict_naming=False)

    # This should then be okay
    client.register("hello5", hello_world, concurrency_queue="nonexisting")
def concurrency_events(*args, **kwargs):
    """ By subclassing swampyer.ConcurrencyQueue, it's possible to manage
        how subscription events and invocations get handed over to the
        handlers.

        In this example, a new class `CustomQueue` is created. It will:

        - Have a default queue size of 5
        - Throw errors once the wait queue grows to 100 (rejects the call)
        - Any procedure that has `bypass` in the URI will skip the queue
        - Log the maximum number of waiting events

    """

    class CustomQueue(swampyer.ConcurrencyQueue):

        def init(self, max_allowed=100):
            self.max_waiting = 0
            self.max_allowed = max_allowed
        
        def job_should_wait(self, event):
            message = event.message

            # We have two possibilities. One is an invoke (to start
            # a function) the other an event for a subscription
            if message == swampyer.WAMP_INVOCATION:

                # In the case of a procedure, if the 2nd element
                # of the args array is True, we will bypass the
                # queue limit check and immediately run the invocation
                if message.args[1]:
                    return False

            elif message == swampyer.WAMP_EVENT:
                print(message.dump())

            return super(CustomQueue,self).job_should_wait(event)

        def queue_init(self, event):

            waiting_jobs = self.waiting_count()

            # Check and log if the number of waiting jobs reaches a new high
            if waiting_jobs > self.max_waiting:
                self.max_waiting = waiting_jobs

            # Then check if the jobs is `self.max_allowed` or more. If so, we throw and error
            # that will get sent back to the client making the call
            if waiting_jobs >= self.max_allowed:
                raise Exception("Exceeded waiting counts")

            # Otherwise proceed normally
            super(CustomQueue,self).queue_init(event)

    client = swampyer.WAMPClient(
                    url="ws://localhost:8282/ws",
                    uri_base="com.example.wamp.api",
                    concurrency_configs={
                        'default': {
                            concurrency_max=5,

                            # Custom keys are passed through into the
                            # `def init` for further usage.
                            max_allowed=100,
                            '_class': CustomQueue
                        }
                    }
                ).start()