Giter VIP home page Giter VIP logo

autobahn-autoreconnect's Introduction

autobahn-autoreconnect

Python Autobahn runner with auto-reconnect feature

Installation

$pip install autobahn-autoreconnect 

Dependencies

autobahn >= 14.0.0

Usage

Just import the ApplicationRunner from autobahn_autoreconnect and it works as a drop in replacement for autobahn.asyncio.wamp.Application Runner.

from autobahn.asyncio.wamp import ApplicationSession
# from autobahn.asyncio.wamp import ApplicationRunner
from autobahn_autoreconnect import ApplicationRunner


class MyComponent(ApplicationSession):
    # awsesome wamp stuff 
  
if __name__ == '__main__':
    runner = ApplicationRunner("ws://localhost:8080/ws", "realm1")
    runner.run(MyComponent)

Retry Strategy

The default retry strategy is the BackoffStrategy based on an increasing time interval starting at 0.5 seconds and doubling until a maximum of 512 seconds before giving up. If you want to override the defaults you can pass in your own BackoffStrategy like so:

from autobahn_autoreconnect import BackoffStrategy

# start with a 10s delay and increase by a factor of 10 until 1000s
# This strategy will wait 10s, 100s and 1000s and then stop retrying
strategy = BackoffStrategy(initial_interval=10, max_interval=1000 factor=10)
runner = ApplicationRunner("ws://localhost:8080/ws", "realm1", retry_strategy=strategy)

Custom Retry Strategies

You can also implement you own retry class by inheriting from autobahn_autoreconnect.IReconnectStrategy.

For example, to retry every second for 100 seconds we could do something like:

from autobahn_autoreconnect import IReconnectStrategy

class OneSecondStrategy(IReconnectStrategy):

    def __init__(self):
        self._retry_counter = 0
  
    def get_retry_interval(self):
        """Return interval, in seconds, to wait between retries"""
        return 1 

    def reset_retry_interval(self):
        """Called before the first time we try to reconnect"""
        self._retry_counter = 0

    def increase_retry_interval(self):
        """Called every time a retry attempt fails"""
        self._retry_counter += 1
    
    def retry(self):
        """Returning True will keep retrying, False will stop retrying"""
        return self._retry_counter < 100
        
runner = ApplicationRunner("ws://localhost:8080/ws", "realm1", retry_strategy=OneSecondStrategy())

autobahn-autoreconnect's People

Contributors

adrienemery avatar aitchkay avatar isra17 avatar trideceth12 avatar tydefriz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

autobahn-autoreconnect's Issues

__init__() got an unexpected keyword arguments: debug and debug_wamp

Not sure if I got wrong version of modules. I need to delete the debug and debug_wamp keyword arguments

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

in init.py of autobahn_autoreconnect module.

My environment is python3.5, autobahn 0.14.1, txaio 2.5.1, autobahn-autoreconnect 0.0.2

Did anyone experience the same thing?

Syntax error on asyncio.async in python 3.8

I get this error in python 3.8.6

File "/Users/hminsky/src/pyleela/venv/lib/python3.8/site-packages/autobahn_autoreconnect/init.py", line 175
asyncio.async(self._connect(), loop=self._loop)
^
SyntaxError: invalid syntax

Is anyone working on a fix for this, or is there some other way to get auto reconnect on asyncio ApplicationRunner these days?

RuntimeError: Event loop is closed

11/6/2016 1:46:36 AM  Connection lost
11/6/2016 1:46:36 AM  Reconnecting
11/6/2016 1:46:36 AM  exception calling callback for <Future at 0x7f841d7e8cf8 state=finished returned list>
11/6/2016 1:46:36 AM  Traceback (most recent call last):
11/6/2016 1:46:36 AM  File "/usr/local/lib/python3.5/concurrent/futures/_base.py", line 297, in _invoke_callbacks
11/6/2016 1:46:36 AM    callback(self)
11/6/2016 1:46:36 AM  File "/usr/local/lib/python3.5/asyncio/futures.py", line 442, in _call_set_state
11/6/2016 1:46:36 AM    dest_loop.call_soon_threadsafe(_set_state, destination, source)
11/6/2016 1:46:36 AM  File "/usr/local/lib/python3.5/asyncio/base_events.py", line 532, in call_soon_threadsafe
11/6/2016 1:46:36 AM    handle = self._call_soon(callback, args)
11/6/2016 1:46:36 AM  File "/usr/local/lib/python3.5/asyncio/base_events.py", line 506, in _call_soon
11/6/2016 1:46:36 AM    self._check_closed()
11/6/2016 1:46:36 AM  File "/usr/local/lib/python3.5/asyncio/base_events.py", line 334, in _check_closed
11/6/2016 1:46:36 AM    raise RuntimeError('Event loop is closed')
11/6/2016 1:46:36 AM  RuntimeError: Event loop is closed

Not entirely sure what's happening.

New Component Instance Is Created After Reconnect

Hi,

Autobahn-autoreconnect is a great tool to converting your WAMP app into a smart and try active connect to WAMP router. It is really cool, thanks for all the work.

Recently, I noticed one thing that when every time WAMP app tries to reconnect, it actually re-instantiate a new object without cleaning up the old object. I assume this is not what we want. Here is my snippet of code


import asyncio
from autobahn_autoreconnect import ApplicationRunner
from autobahn.asyncio.wamp import ApplicationSession

class Component(ApplicationSession):
    def __init__(self, config):
        super(Component, self).__init__(config)
        self.myState = 0
        async def printState():
            print("{} state {}".format(self, self.myState))
            await asyncio.sleep(5)

        asyncio.ensure_future(printState)

    def onDisconnect(self):
        # asyncio.get_event_loop().stop()
        self.myState = -1
        print("Connect drops, autoreconnect should kick in")

if __name__ == "__main__":
    runner = ApplicationRunner(
            u"wss://1.2.3.4:443/ws",
            u"realm1",
            debug_app=True
    )
    runner.run(Component)

You will need to have a WAMP router to connect to and disconnect the network to fall into the reconnect cycle. You will see two outputs printing myState = -1 and myState =0 when you successfully reconnect.

Any advice?

New Stable Release

Hi,

Currently, the stable PIP release is 0.1.0 but it doesn't include the fix of

try:
    self._loop.add_signal_handler(signal.SIGTERM, self.stop)
except NotImplementedError:
    pass

Even this is a small fix, do we have a plan to release a new PIP package? Thanks

Reconnect Issue

Hi,

The reconnect functionality seems to be working in certain condition. Maybe I am missing some configurations. I can see ApplicationRunner try to reconnect when it fails initially

my stdout

Connection failed
Retry in 0.5 seconds
Connection failed
Retry in 1 seconds

which is awesome. However, if the network connection drops in the middle of operation, it doesn't seem to kick start the _reconnect() function again. I don't see

Connection lost
Reconnecting

in my stdout. Here is my code

from autobahn_autoreconnect import ApplicationRunner, BackoffStrategy

class ISIBackoffStrategy(BackoffStrategy):
    '''
    retry incremental 0.5, 1, 2. 4, ... 32 seconds then retry every 32 seconds
    '''
    def __init__(self, max_retry_interval=32):
        super().__init__()
        self._max_retry_interval = max_retry_interval

    def increase_retry_interval(self):
        if self._retry_interval < self._max_retry_interval:
            self._retry_interval *= self._factor

    def retry(self):
        # retry forever
        return True

if __name__ == '__main__':
    runner = ApplicationRunner(
            os.environ.get("AUTOBAHN_DEMO_ROUTER", u"ws://whatever.com/ws"),
            u"realm1",
            retry_strategy=ISIBackoffStrategy(),
            debug_app=True,
        )
    runner.run(Component)

I am still learning asyncio. Thanks for you help.

Proxy Support

Hi,

Have we consider to add the proxy support? Here is an example code snippet. In ApplicationRunner class,

Line 95: def init(self, url, realm, extra=None, serializers=None, debug_app=False, proxy=None,
Line 127:+ self._proxy=proxy
Line 169: self._transport_factory = WampWebSocketClientFactory(_create_app_session, url=self._url, serializer=self._serializer, proxy=self._proxy)

Python: import autobahn_autoreconnect causes RuntimeError

When I install it on Ubuntu + Python 3.5 with pip3 install autobahn-autoreconnect and then use import autobahn_autoreconnect I get the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/dist-packages/autobahn_autoreconnect/__init__.py", line 31, in <module>
    from autobahn.wamp import protocol
  File "/usr/local/lib/python3.5/dist-packages/autobahn/wamp/protocol.py", line 272, in <module>
    class ApplicationSession(BaseSession):
  File "/usr/local/lib/python3.5/dist-packages/autobahn/wamp/protocol.py", line 277, in ApplicationSession
    log = txaio.make_logger()
  File "/usr/local/lib/python3.5/dist-packages/txaio/_unframework.py", line 43, in _throw_usage_error
    "To use txaio, you must first select a framework "
RuntimeError: To use txaio, you must first select a framework with .use_twisted() or .use_asyncio()

What am I doing wrong?

SyntaxError: invalid syntax on __init__.py

Hi

I am getting the following error:

from autobahn_autoreconnect import ApplicationRunner

File "/usr/local/lib/python2.7/dist-packages/autobahn_autoreconnect/init.py", line 195
_, protocol = yield from self._loop.create_connection(self._transport_factory, self._host, self._port, ssl=self._ssl)
SyntaxError: invalid syntax

Any idea why?

Asyncio add_signal_handler function not implemented in windows

In windows I get

Traceback (most recent call last):
File "autobahn_wamp_reconnecting_client_3.py", line 74, in
File "autobahn_wamp_reconnecting_client_3.py", line 71, in doRun
File "site-packages\autobahn_autoreconnect_init_.py", line 174, in run
File "asyncio\events.py", line 475, in add_signal_handler
NotImplementedError
Failed to execute script autobahn_wamp_reconnecting_client_3

line 174

self._loop.add_signal_handler(signal.SIGTERM, self.stop)

The fix could be

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

as dealt with by the folks in autobahn in crossbario/autobahn-python#471

Detect a connection drop based on server-side heartbeats

I've got a setup where a client is listening to a server that sends out a constant stream of messages. In the unlikely event that no message occurs for more than X seconds, the server sends out an empty heartbeat message.

Detecting a connection drop here should be really simple: if no message has arrived in X seconds, we can consider the connection dropped. There is no need to send pings to the server.

Any ideas how to best implement something like this in the autobahn-autoreconnect runner? The problem I'm having is that I don't control the event loop, so when no new message occurs, my code isn't called.

Component Doesn't Get Created If Never Connected

Hi,

If the session is never established, the component won't be created. However, there are some functions that I need to run even not connected. However, if the connection drops intermittently, component is created, loop is still running, everything is cool. The question will be how can I instantiate the component even when the connection can't be established initially.

Thank you for the great module and help.

"Task was destroyed but it is pending!"

Sometimes I get this warning on a reconnect:

Task was destroyed but it is pending!
task: <Task pending coro=<onJoin() running at ...> wait_for=<Future pending cb=[Task._wakeup()]>>```

dropping connection to peer tcp:my_ip:443 with abort=True: WebSocket connection upgrade failed (502 - BadGateway)

i use ws or wss to connect my crossbar by nginx proxy

    server {
        listen              443;
        ssl on;
        ssl_certificate /etc/nginx/ssl/chained.pem;
        ssl_certificate_key /etc/nginx/ssl/sg-ai.key;
        server_name test.sg-ai.com;
        location /  {
            proxy_pass http://172.16.10.17:28080; # my crossbar server 
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_connect_timeout 4s;
            proxy_read_timeout 86400s;
            proxy_send_timeout 12s;
        }
    }

if i stop my crossbar it always report like this :

Connection lost
Reconnecting
dropping connection to peer tcp:123.59.182.185:443 with abort=True: WebSocket connection upgrade failed (502 - BadGateway)
Connection lost
Reconnecting
dropping connection to peer tcp:123.59.182.185:443 with abort=True: WebSocket connection upgrade failed (502 - BadGateway)

it out of my time and never stopped.

    strategy = BackoffStrategy(initial_interval=1, max_interval=5, factor=2)
    runner = ApplicationRunner(url=u'wss://mydomain/ws', realm=u'realm1', ssl=True, retry_strategy=strategy)
    runner.run(ClientSession)

when i do not to use nginx proxy to connect my crossbar ,its fine .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.