Skip to content
This repository has been archived by the owner on Jan 5, 2021. It is now read-only.

Commit

Permalink
Fixes #26: Deal slightly better with caching; this will need a big re…
Browse files Browse the repository at this point in the history
…factor to do properly.
  • Loading branch information
iancmcc committed Aug 11, 2014
1 parent 51e1e21 commit b7f6ffa
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
3 changes: 3 additions & 0 deletions ouimeaux/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ def server(args):


def wemo():
import ouimeaux.utils
ouimeaux.utils._RETRIES = 0

parser = argparse.ArgumentParser()

parser.add_argument("-b", "--bind", default=None,
Expand Down
10 changes: 10 additions & 0 deletions ouimeaux/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,21 @@ def __init__(self, shelf):
def empty(self):
return not self._shelf.get('devices')

def clear(self):
self._shelf.clear()

def add_device(self, device):
assert isinstance(device, Device)
d = self._shelf.setdefault('devices', {})
d[device.name] = device

def invalidate(self, device):
assert isinstance(device, Device)
d = self._shelf.setdefault('devices', {})
d.pop(device.name)
self._shelf.clear()
self._shelf['devices'] = d

@property
def devices(self):
try:
Expand Down
7 changes: 7 additions & 0 deletions ouimeaux/device/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
log = logging.getLogger(__name__)


class DeviceUnreachable(Exception): pass
class UnknownService(Exception): pass


Expand Down Expand Up @@ -55,6 +56,12 @@ def get_service(self, name):
def list_services(self):
return self.services.keys()

def ping(self):
try:
self.get_state()
except Exception:
raise DeviceUnreachable(self)

def explain(self):
for name, svc in self.services.iteritems():
print name
Expand Down
13 changes: 10 additions & 3 deletions ouimeaux/environment.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging

import gevent
import requests

from ouimeaux.config import get_cache, WemoConfiguration
from ouimeaux.device import DeviceUnreachable
from ouimeaux.device.switch import Switch
from ouimeaux.device.insight import Insight
from ouimeaux.device.lightswitch import LightSwitch
Expand Down Expand Up @@ -151,9 +153,14 @@ def _process_device(self, device, cache=None):
self.registry.register(device)
self.registry.on(device, 'BinaryState',
device._update_state)
if cache if cache is not None else self._with_cache:
with get_cache() as c:
c.add_device(device)
with get_cache() as c:
try:
device.ping()
except DeviceUnreachable:
return
else:
if cache if cache is not None else self._with_cache:
c.add_device(device)
devicefound.send(device)
callback(device)

Expand Down
25 changes: 16 additions & 9 deletions ouimeaux/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,35 @@ def matches(s):
return matches


def retry_with_delay(f, retries=10, delay=60):
# This is pretty arbitrary. I'm choosing, for no real reason, the length of
# a subscription.
_RETRIES = 1801/60


def get_retries():
return _RETRIES


def retry_with_delay(f, delay=60):
"""
Retry the wrapped requests.request function in case of ConnectionError.
Optionally limit the number of retries or set the delay between retries.
"""
@wraps(f)
def inner(*args, **kwargs):
remaining = retries
kwargs['timeout'] = 1
remaining = get_retries() + 1
while remaining:
remaining -= 1
try:
return f(*args, **kwargs)
except requests.ConnectionError:
if not remaining:
raise
remaining -= 1
gevent.sleep(delay)
return inner


# This is pretty arbitrary. I'm choosing, for no real reason, the length of
# a subscription.
_RETRIES = 1801/60
requests_get = retry_with_delay(requests.get, retries=_RETRIES)
requests_post = retry_with_delay(requests.post, retries=_RETRIES)
requests_request = retry_with_delay(requests.request, retries=_RETRIES)
requests_get = retry_with_delay(requests.get)
requests_post = retry_with_delay(requests.post)
requests_request = retry_with_delay(requests.request)

0 comments on commit b7f6ffa

Please sign in to comment.