# Path: zoonado/exc.py
# class ZKError(Exception):
# class ConnectError(ZKError):
# class NoServersError(ZKError):
# class SessionLost(ZKError):
# class InvalidClientState(ZKError):
# class TimeoutError(ZKError):
# class FailedRetry(ZKError):
# class ResponseErrorMeta(type):
# class ResponseError(ZKError):
# class UnknownError(ResponseError):
# class RolledBack(ResponseError):
# class ZKSystemError(ResponseError):
# class RuntimeInconsistency(ResponseError):
# class DataInconsistency(ResponseError):
# class ConnectionLoss(ResponseError):
# class MarshallingError(ResponseError):
# class Unimplemented(ResponseError):
# class OperationTimeout(ResponseError):
# class BadArguments(ResponseError):
# class UnknownSession(ResponseError):
# class NewConfigNoQuorum(ResponseError):
# class ReconfigInProcess(ResponseError):
# class APIError(ResponseError):
# class NoNode(ResponseError):
# class NoAuth(ResponseError):
# class BadVersion(ResponseError):
# class NoChildrenForEphemerals(ResponseError):
# class NodeExists(ResponseError):
# class NotEmpty(ResponseError):
# class SessionExpired(ResponseError):
# class InvalidCallback(ResponseError):
# class InvalidACL(ResponseError):
# class AuthFailed(ResponseError):
# class SessionMoved(ResponseError):
# class NotReadOnly(ResponseError):
# class EphemeralOnLocalSession(ResponseError):
# class NoWatcher(ResponseError):
#     def __init__(self, host, port, server_id=None):
#     def __str__(self):
#     def __new__(cls, name, bases, attrs):
#     def __str__(self):
#     def __init__(self, error_code):
#     def __str__(self):
# def get_response_error(error_code):


import collections
import logging
import time
from tornado import gen
from zoonado import exc




log = logging.getLogger(__name__)


class RetryPolicy(object):

    def __init__(self, try_limit, sleep_func):
        self.try_limit = try_limit
        self.sleep_func = sleep_func

        self.timings = collections.defaultdict(list)

    @gen.coroutine
    def enforce(self, request=None):
        self.timings[id(request)].append(time.time())

        tries = len(self.timings[id(request)])
        if tries == 1:
            return

        if self.try_limit is not None and tries >= self.try_limit:
            raise exc.FailedRetry

        wait_time = self.sleep_func(self.timings[id(request)])
        if wait_time is None or wait_time == 0:
            return
        elif wait_time < 0:

# Path: zoonado/exc.py
# class ZKError(Exception):
# class ConnectError(ZKError):
# class NoServersError(ZKError):
# class SessionLost(ZKError):
# class InvalidClientState(ZKError):
# class TimeoutError(ZKError):
# class FailedRetry(ZKError):
# class ResponseErrorMeta(type):
# class ResponseError(ZKError):
# class UnknownError(ResponseError):
# class RolledBack(ResponseError):
# class ZKSystemError(ResponseError):
# class RuntimeInconsistency(ResponseError):
# class DataInconsistency(ResponseError):
# class ConnectionLoss(ResponseError):
# class MarshallingError(ResponseError):
# class Unimplemented(ResponseError):
# class OperationTimeout(ResponseError):
# class BadArguments(ResponseError):
# class UnknownSession(ResponseError):
# class NewConfigNoQuorum(ResponseError):
# class ReconfigInProcess(ResponseError):
# class APIError(ResponseError):
# class NoNode(ResponseError):
# class NoAuth(ResponseError):
# class BadVersion(ResponseError):
# class NoChildrenForEphemerals(ResponseError):
# class NodeExists(ResponseError):
# class NotEmpty(ResponseError):
# class SessionExpired(ResponseError):
# class InvalidCallback(ResponseError):
# class InvalidACL(ResponseError):
# class AuthFailed(ResponseError):
# class SessionMoved(ResponseError):
# class NotReadOnly(ResponseError):
# class EphemeralOnLocalSession(ResponseError):
# class NoWatcher(ResponseError):
#     def __init__(self, host, port, server_id=None):
#     def __str__(self):
#     def __new__(cls, name, bases, attrs):
#     def __str__(self):
#     def __init__(self, error_code):
#     def __str__(self):
# def get_response_error(error_code):


# Path: zoonado/retry.py
import collections
import logging
import time
from tornado import gen
from zoonado import exc





log = logging.getLogger(__name__)


class RetryPolicy(object):

    def __init__(self, try_limit, sleep_func):
        self.try_limit = try_limit
        self.sleep_func = sleep_func

        self.timings = collections.defaultdict(list)

    @gen.coroutine
    def enforce(self, request=None):
        self.timings[id(request)].append(time.time())

        tries = len(self.timings[id(request)])
        if tries == 1:
            return

        if self.try_limit is not None and tries >= self.try_limit:
            raise exc.FailedRetry

        wait_time = self.sleep_func(self.timings[id(request)])
        if wait_time is None or wait_time == 0:
            return
        elif wait_time < 0:

            raise exc.FailedRetry