Skip to content

Commit

Permalink
Rework ZGS cache strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
jjlawren committed Dec 23, 2023
1 parent 54bcfac commit d32410c
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 11 deletions.
6 changes: 6 additions & 0 deletions soco/events_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ def success(headers):
# Autorenew just before expiry, say at 85% of self.timeout seconds
interval = self.timeout * 85 / 100
self._auto_renew_start(interval)
if service.service_type == "ZoneGroupTopology":
service.soco.zone_group_state.extend_cache(self.timeout)

# Lock out EventNotifyHandler during registration.
# If events_twisted is used, this lock should always be
Expand Down Expand Up @@ -523,6 +525,8 @@ def success(headers):
self.service.base_url + self.service.event_subscription_url,
self.sid,
)
if self.service.service_type == "ZoneGroupTopology":
self.service.soco.zone_group_state.extend_cache(self.timeout)

return self._request(
"SUBSCRIBE",
Expand Down Expand Up @@ -653,6 +657,8 @@ def _cancel_subscription(self, msg=None):
# an attempt to unsubscribe fails
self._has_been_unsubscribed = True
self._timestamp = None
if self.service.service_type == "ZoneGroupTopology":
self.service.soco.zone_group_state.clear_cache()
# Cancel any auto renew
self._auto_renew_cancel()
if msg:
Expand Down
17 changes: 6 additions & 11 deletions soco/zonegroupstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ def clear_cache(self):
"""Clear the cache timestamp."""
self._cache_until = NEVER_TIME

def extend_cache(self, timeout=EVENT_CACHE_TIMEOUT):
"""Extend the cache timeout."""
self._cache_until = time.monotonic() + timeout
_LOG.debug("Extending ZGS cache by %ss", timeout)

def clear_zone_groups(self):
"""Clear all known group sets."""
self.groups.clear()
Expand Down Expand Up @@ -156,6 +161,7 @@ def poll(self, soco):
try:
zgs = soco.zoneGroupTopology.GetZoneGroupState()["ZoneGroupState"]
self.process_payload(payload=zgs, source="poll", source_ip=soco.ip_address)
self.extend_cache(POLLING_CACHE_TIMEOUT)

# In the event of failure, we fall back to using a ZGT event to
# determine the ZGS. Fallback behaviour can be disabled by setting the
Expand Down Expand Up @@ -244,22 +250,12 @@ async def update_zgs_by_event_asyncio(speaker):
def process_payload(self, payload, source, source_ip):
"""Update using the provided XML payload."""
self.total_requests += 1

def update_cache():
if source == "event":
timeout = EVENT_CACHE_TIMEOUT
else:
timeout = POLLING_CACHE_TIMEOUT
self._cache_until = time.monotonic() + timeout
_LOG.debug("Setting ZGS cache to %ss", timeout)

tree = normalize_zgs_xml(payload)
normalized_zgs = str(tree)
if normalized_zgs == self._last_zgs:
_LOG.debug(
"Duplicate ZGS received from %s (%s), ignoring", source_ip, source
)
update_cache()
return

self.processed_count += 1
Expand All @@ -272,7 +268,6 @@ def update_cache():
)

self.update_soco_instances(tree)
update_cache()
self._last_zgs = normalized_zgs

def parse_zone_group_member(self, member_element):
Expand Down

0 comments on commit d32410c

Please sign in to comment.