Fix race in component registry

A data watcher works by receiving an event from ZK and subsequently
fetching the data.  That means that the data are guaranteed to be
at least as new as the event, but possibly newer.

Consider the following sequence:

* [1] component sets state to "stopped"
* [2] zk emits "changed" event for component's znode
* [1] component disconnects
* [2] zk deletes ephemeral component znode
* [3] registry datawatch receives changed event
* [3] registry datawatch performs 'get' on znode
* [3] znode does not exist, raises NoNodeError, data=None
* [3] datawatch calls our watcher with event=changed data=None

We should treat this case as the node having been deleted.

Change-Id: I317c62e328fe2074f79451656a3a227ebe1f447d
This commit is contained in:
James E. Blair 2021-08-06 07:21:24 -07:00
parent c30eca959a
commit 4f96125007
1 changed files with 3 additions and 5 deletions

View File

@ -249,10 +249,8 @@ class ComponentRegistry(ZooKeeperBase):
self.log.debug(
"Registry %s got event %s for %s %s",
self, etype, kind, hostname)
if etype in (None, EventType.CHANGED, EventType.CREATED):
# Ignore events without data
if not data:
return
if (etype in (None, EventType.CHANGED, EventType.CREATED) and
data is not None):
# Perform an in-place update of the cached component (if any)
component = self._cached_components.get(kind, {}).get(hostname)
@ -280,7 +278,7 @@ class ComponentRegistry(ZooKeeperBase):
component._zstat = stat
self._cached_components[kind][hostname] = component
elif etype == EventType.DELETED:
elif (etype == EventType.DELETED or data is None):
self.log.info(
"Noticed %s component %s disappeared",
kind, hostname)