On Wed, Sep 23, 2009 at 04:08:00PM +0100, Guido Trotter wrote:
> 
> This callback can be stacked with another one, and will filter duplicate
> results.
> 
> Signed-off-by: Guido Trotter <[email protected]>
> ---
>  lib/confd/client.py |   66 
> +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 66 insertions(+), 0 deletions(-)
> 
> diff --git a/lib/confd/client.py b/lib/confd/client.py
> index 53d1673..672a984 100644
> --- a/lib/confd/client.py
> +++ b/lib/confd/client.py
> @@ -271,3 +271,69 @@ class ConfdClientRequest(objects.ConfdRequest):
>      if self.type not in constants.CONFD_REQS:
>        raise errors.ConfdClientError("Invalid request type")
>  
> +
> +class ConfdFilterCallback:
> +  """Callback that calls another callback, but filters duplicate results.
> +
> +  """
> +  def __init__(self, callback, logger=None):
> +    """Constructor for ConfdFilterCallback
> +
> +    @type callback: f(L{ConfdUpcallPayload})
> +    @param callback: function to call when getting answers
> +    @type logger: L{logging.Logger}
> +    @keyword logger: optional logger for internal conditions
> +
> +    """
> +    if not callable(callback):
> +      raise errors.ProgrammerError("callback must be callable")
> +
> +    self._callback = callback
> +    self._logger = logger
> +    # answers contains a dict of salt -> answer
> +    self._answers = {}
> +
> +  def __call__(self, up):
> +    """Filtering callback
> +
> +    @type up: L{ConfdUpcallPayload}
> +    @param up: upper callback
> +
> +    """
> +    salt = up.salt
> +    filter = False
> +    if up.type == UPCALL_REPLY:
> +      if salt in self._answers:
> +        old_answer = self._answers[salt]
> +        new_answer = up.server_reply
> +        if new_answer.serial > old_answer.serial:
> +          self._answers[salt] = up.server_reply
> +          if new_answer.answer == old_answer.answer:
> +            self._logger.debug("Filtering confirming answer, with newer"
> +              " serial for query %s" % salt)
> +            filter = True
> +        elif new_answer.serial == old_answer.serial:
> +          filter = True
> +          if self._logger:
> +            if new_answer.answer != old_answer.answer:
> +              self._logger.debug("Got incoherent answers for query %s"
> +                " (serial: %s)" % (salt, new_answer.serial))
> +            else:
> +              self._logger.debug("Filtering confirming answer, with same"
> +                " serial for query %s" % salt)
> +        else:
> +          filter = True
> +          if self._logger:
> +            self._logger.debug("Filtering outdated answer for query %s"
> +              " serial: (%d < %d)" % (salt, old_answer.serial, 
> new_answer.serial))
> +      else:
> +        self._answers[salt] = up.server_reply
> +    elif up.type == UPCALL_EXPIRE:
> +      if salt in self._answers:
> +        del self._answers[salt]
> +
> +    if not filter:
> +      return self._callback(up)
> +    else:
> +      return

Uh, wrong indentation for the messages and look like a very indented
(stair-case) code. Could yu either split it in multiple functions or add some
comments?

iustin

Reply via email to