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:
parent
c30eca959a
commit
4f96125007
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue