Skip to content

Commit

Permalink
Fixed the web socket reconnection handling to use exponential retry b…
Browse files Browse the repository at this point in the history
…ack off.
  • Loading branch information
randompi committed Mar 10, 2016
1 parent 8fca61c commit e05562f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 12 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Development

Its recommended to setup a virtual environment, e.g. `virtualenv venv`.

Then do `pip install requirements.txt`

You will need the following env vars set. In Prod, these would be passed in via Beep Boop.

`export BEEPBOOP_TOKEN=foo`
Expand All @@ -10,4 +14,5 @@ You will need the following env vars set. In Prod, these would be passed in via

`export BEEPBOOP_RESOURCER=ws://localhost:9000/ws` -- recommend using the [Beep Boop dev-console](https://github.com/BeepBoopHQ/dev-console) and setting this value to it.

Run `python ./examples/simple.py` which registers listeners as a consuming app might.
Run `python ./examples/simple.py` which registers listeners as a consuming app might. Note you may need to set `export PYTHONPATH=.` so that
it can properly import the beepboop module.
27 changes: 18 additions & 9 deletions beepboop.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
logging.basicConfig(format='%(asctime)s - %(levelname)s: %(message)s', level=log_level)
logger = logging.getLogger(__name__)

sys.path.append('/Users/skud/projects/src/github.com/BeepBoopHQ/websocket-client')
import websocket
import random


class BeepBoop(object):
Expand Down Expand Up @@ -43,10 +43,15 @@ def start(self):
def handlers(self, handler_funcs_dict):
self.handler_funcs = handler_funcs_dict


def _connect(self):
self.iter += 1
print ('iteration: ' + str(self.iter))
self.ws_app.run_forever()
# while loop makes sure we retry to connect on server down or network failure
while True:
self.ws_app.run_forever()
self.iter += 1
logging.debug('reconnecting attempt: ' + str(self.iter))
expBackoffSleep(self.iter, 32)


def on_message(self, ws, message):
if self.handler_funcs['on_message']:
Expand All @@ -60,14 +65,11 @@ def on_close(self, ws):
if self.handler_funcs['on_close']:
self.handler_funcs['on_close'](ws)

# must be connected to the resourcer so we need to keep "retrying".
# NOTE: websocket lib should handle cleanup but i'm seeing leaking
time.sleep(1)
self._connect()

def on_open(self, ws):
self.ws_conn = ws
self._authorize()
# reset to 0 since we've reopened a connection
self.iter = 0
if self.handler_funcs['on_open']:
self.handler_funcs['on_open'](ws)

Expand All @@ -88,3 +90,10 @@ def _getprop(self, param, env_var):
exit()

return v

# Use binary exponential backoff to desynchronize client requests.
# As described by: https://cloud.google.com/storage/docs/exponential-backoff
def expBackoffSleep(n, max_backoff_time):
time_to_sleep = min(random.random() * (2**n), max_backoff_time)
logging.debug('time to sleep: ' + str(time_to_sleep))
time.sleep(time_to_sleep)
1 change: 0 additions & 1 deletion examples/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import sys
import os
import pprint
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))

import beepboop

Expand Down
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
websocket-client>=0.22.0
six==1.10.0
websocket-client==0.35.0
wheel==0.24.0

0 comments on commit e05562f

Please sign in to comment.