Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pychromecast/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def remove_service(self, zconf, typ, name):
_LOGGER.debug("remove_service %s, %s", typ, name)
service = self.services.pop(name, None)

if not service:
_LOGGER.debug("remove_service unknown %s, %s", typ, name)
return

if self.remove_callback:
self.remove_callback(name, service)

Expand All @@ -52,6 +56,7 @@ def add_service(self, zconf, typ, name):
tries += 1

if not service:
_LOGGER.debug("add_service failed to add %s, %s", typ, name)
return

def get_value(key):
Expand Down
21 changes: 13 additions & 8 deletions pychromecast/socket_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,13 @@ def initialize_connection(self): # noqa: E501 pylint:disable=too-many-statement
# Dict keeping track of individual retry delay for each named service
retries = {}

def mdns_backoff(service, retry):
"""Exponentional backoff for service name mdns lookups."""
now = time.time()
retry['next_retry'] = now + retry['delay']
retry['delay'] = min(retry['delay']*2, 300)
retries[service] = retry

while not self.stop.is_set() and (tries is None or tries > 0): # noqa: E501 pylint:disable=too-many-nested-blocks
# Prune retries dict
retries = {key: retries[key] for key in self.services if (
Expand All @@ -254,6 +261,9 @@ def initialize_connection(self): # noqa: E501 pylint:disable=too-many-statement
now = time.time()
retry = retries.get(
service, {'delay': self.retry_wait, 'next_retry': now})
# If we're connecting to a named service, check if it's time
if service and now < retry['next_retry']:
continue
try:
self.socket = new_socket()
self.socket.settimeout(self.timeout)
Expand All @@ -263,8 +273,6 @@ def initialize_connection(self): # noqa: E501 pylint:disable=too-many-statement
# Resolve the service name. If service is None, we're
# connecting directly to a host name or IP-address
if service:
if now < retry['next_retry']:
continue
host = None
port = None
service_info = get_info_from_service(service,
Expand All @@ -284,12 +292,13 @@ def initialize_connection(self): # noqa: E501 pylint:disable=too-many-statement
self.port = port
else:
self.logger.debug(
"[%s:%s] failed to resolve service %s",
"[%s:%s] Failed to resolve service %s",
self.fn or self.host, self.port, service)
self._report_connection_status(
ConnectionStatus(
CONNECTION_STATUS_FAILED_RESOLVE,
NetworkAddress(service, None)))
mdns_backoff(service, retry)
# If zeroconf fails to receive the necessary data,
# try next service
continue
Expand Down Expand Up @@ -324,16 +333,12 @@ def initialize_connection(self): # noqa: E501 pylint:disable=too-many-statement
ConnectionStatus(CONNECTION_STATUS_FAILED,
NetworkAddress(self.host, self.port)))
if service is not None:
# Exponentional backoff for service name mdns lookups
now = time.time()
retry['next_retry'] = now + retry['delay']
retry_log_fun(
"[%s:%s] Failed to connect to service %s"
", retrying in %.1fs",
self.fn or self.host, self.port,
service, retry['delay'])
retry['delay'] = min(retry['delay']*2, 300)
retries[service] = retry
mdns_backoff(service, retry)
else:
retry_log_fun(
"[%s:%s] Failed to connect, retrying in %.1fs",
Expand Down