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")
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))
#!/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: #
#!/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))
- 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()