From 49b3fdacf04c3746e56d754a2fc0178c23c2259b Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Thu, 18 Mar 2010 16:46:54 +0100 Subject: [PATCH] Extend ConfdFilterCallback with consistency checks Note that users of the callback will have to manually check the attribute. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- lib/confd/client.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/confd/client.py b/lib/confd/client.py index dfbc65063..71b510435 100644 --- a/lib/confd/client.py +++ b/lib/confd/client.py @@ -347,6 +347,12 @@ class ConfdClientRequest(objects.ConfdRequest): class ConfdFilterCallback: """Callback that calls another callback, but filters duplicate results. + @ivar consistent: a dictionary indexed by salt; for each salt, if + all responses ware identical, this will be True; this is the + expected state on a healthy cluster; on inconsistent or + partitioned clusters, this might be False, if we see answers + with the same serial but different contents + """ def __init__(self, callback, logger=None): """Constructor for ConfdFilterCallback @@ -364,6 +370,7 @@ class ConfdFilterCallback: self._logger = logger # answers contains a dict of salt -> answer self._answers = {} + self.consistent = {} def _LogFilter(self, salt, new_reply, old_reply): if not self._logger: @@ -388,6 +395,8 @@ class ConfdFilterCallback: # if we have no answer we have received none, before the expiration. if up.salt in self._answers: del self._answers[up.salt] + if up.salt in self.consistent: + del self.consistent[up.salt] def _HandleReply(self, up): """Handle a single confd reply, and decide whether to filter it. @@ -399,6 +408,8 @@ class ConfdFilterCallback: """ filter_upcall = False salt = up.salt + if salt not in self.consistent: + self.consistent[salt] = True if salt not in self._answers: # first answer for a query (don't filter, and record) self._answers[salt] = up.server_reply @@ -413,6 +424,8 @@ class ConfdFilterCallback: # else: different content, pass up a second answer else: # older or same-version answer (duplicate or outdated, filter) + if up.server_reply.answer != self._answers[salt].answer: + self.consistent[salt] = False filter_upcall = True self._LogFilter(salt, up.server_reply, self._answers[salt]) -- GitLab