本文整理汇总了Python中kazoo.retry.KazooRetry类的典型用法代码示例。如果您正苦于以下问题:Python KazooRetry类的具体用法?Python KazooRetry怎么用?Python KazooRetry使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了KazooRetry类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: __init__
def __init__(self, client, keys, txid=None):
""" Create an entity lock.
Args:
client: A kazoo client.
keys: A list of entity Reference objects.
txid: An integer specifying the transaction ID.
"""
self.client = client
self.paths = [zk_group_path(key) for key in keys]
# The txid is written to the contender nodes for deadlock resolution.
self.data = str(txid or '')
self.wake_event = client.handler.event_object()
# Give the contender nodes a uniquely identifiable prefix in case its
# existence is in question.
self.prefix = uuid.uuid4().hex + self._NODE_NAME
self.create_paths = [path + '/' + self.prefix for path in self.paths]
self.create_tried = False
self.is_acquired = False
self.cancelled = False
self._retry = KazooRetry(max_tries=None,
sleep_func=client.handler.sleep_func)
self._lock = client.handler.lock_object()
示例2: __init__
def __init__(self, module, server_list):
# logging
logger = logging.getLogger(module)
logger.setLevel(logging.INFO)
try:
handler = logging.handlers.RotatingFileHandler('/var/log/contrail/' + module + '-zk.log', maxBytes=10*1024*1024, backupCount=5)
except IOError:
print "Cannot open log file in /var/log/contrail/"
else:
log_format = logging.Formatter('%(asctime)s [%(name)s]: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
handler.setFormatter(log_format)
logger.addHandler(handler)
self._zk_client = \
kazoo.client.KazooClient(
server_list,
timeout=20,
handler=kazoo.handlers.gevent.SequentialGeventHandler(),
logger=logger)
self._zk_client.add_listener(self._zk_listener)
self._logger = logger
self._election = None
# KazooRetry to retry keeper CRUD operations
self._retry = KazooRetry(max_tries=None)
self.connect()
示例3: __init__
def __init__(self, client, path, identifier=None):
"""Create a Kazoo lock.
:param client: A :class:`~kazoo.client.KazooClient` instance.
:param path: The lock path to use.
:param identifier: Name to use for this lock contender. This
can be useful for querying to see who the
current lock contenders are.
"""
self.client = client
self.path = path
# some data is written to the node. this can be queried via
# contenders() to see who is contending for the lock
self.data = str(identifier or "").encode("utf-8")
self.wake_event = client.handler.event_object()
# props to Netflix Curator for this trick. It is possible for our
# create request to succeed on the server, but for a failure to
# prevent us from getting back the full path name. We prefix our
# lock name with a uuid and can check for its presence on retry.
self.prefix = uuid.uuid4().hex + self._NODE_NAME
self.create_path = self.path + "/" + self.prefix
self.create_tried = False
self.is_acquired = False
self.assured_path = False
self.cancelled = False
self._retry = KazooRetry(max_tries=None, sleep_func=client.handler.sleep_func)
self._lock = client.handler.lock_object()
示例4: rebalance
def rebalance(self, partition_ids=None):
if partition_ids is None:
partition_ids = [
str(p_id)
for p_id in self.consumer_partitions[self._identifier]
]
kr = KazooRetry(max_tries=3)
kr.retry_exceptions = kr.retry_exceptions + tuple([NodeExistsError])
my_partitions = self.consumer_partitions[self._identifier]
self.logger.info('My partitions (%d): %s', len(my_partitions), my_partitions)
# Clean up old ownership data first, so we don't block
# the joining node(s)
self._release_locks()
nodes = sorted([node for node in self._group], key=lambda x: hash(x))
my_new_partitions = [
partition
for partition in partition_ids
if nodes[int(partition) % len(nodes)] == self._identifier and
int(partition) not in my_partitions
]
self.logger.info('My new partitions (%d): %s', len(my_new_partitions), my_new_partitions)
for partition in my_new_partitions:
c_id = nodes[int(partition) % len(nodes)]
self.consumer_partitions[c_id].append(int(partition))
p_path = self.path_formats['owner'].format(group=self.group,
topic=self.topic,
partition=partition)
try:
self.logger.debug('Acquiring ownership of partition %s',
partition)
kr(self._client.create, p_path,
value=self._identifier, ephemeral=True, makepath=True)
except RetryFailedError as err:
# A different consumer had been registered as the owner
expired_cid, zstat = self._client.get(p_path)
msg = 'Acquiring ownership of partition %s (was owned by %s)'
self.logger.warn(msg, partition, expired_cid)
# We need to delete / create, so that the node is created
# ephemeral and owned by us
self._client.delete(p_path)
self._client.create(p_path, value=self._identifier,
ephemeral=True, makepath=True)
if self.partitions_changed_cb:
self.partitions_changed_cb(self.consumer_partitions[self._identifier])
示例5: rebalance
def rebalance(self, partition_ids=None):
if partition_ids is None:
partition_ids = [
str(p_id)
for p_id in self.consumer_partitions[self._identifier]
]
kr = KazooRetry(max_tries=3)
kr.retry_exceptions = kr.retry_exceptions + tuple([NodeExistsError])
my_partitions = self.consumer_partitions[self._identifier]
self.logger.info('My partitions (%d): %s',
len(my_partitions), my_partitions)
# Clean up old ownership data first, so we don't block
# the joining node(s)
self._release_locks()
nodes = sorted([node for node in self._group])
self.logger.info('Connected nodes (%d): %s',
len(nodes), nodes)
my_new_partitions = [
partition
for partition in partition_ids
if nodes[int(partition) % len(nodes)] == self._identifier and
int(partition) not in my_partitions
]
self.logger.info('My new partitions (%d): %s',
len(my_new_partitions), my_new_partitions)
for partition in my_new_partitions:
c_id = nodes[int(partition) % len(nodes)]
self.consumer_partitions[c_id].append(int(partition))
p_path = self.path_formats['owner'].format(group=self.group,
topic=self.topic,
partition=partition)
try:
self.logger.debug('Acquiring ownership of partition %s',
partition)
kr(self._client.create, p_path,
value=self._identifier, ephemeral=True, makepath=True)
except RetryFailedError:
# A different consumer is still connected and owns this,
# try to gracefully release everything else and fail out
self.finish()
if self.partitions_changed_cb:
self.partitions_changed_cb(self.consumer_partitions[self._identifier])
示例6: __init__
def __init__(self, client, path, identifier=None, exclusive=True):
"""Create a Kazoo lock.
:param client: The Kazoo client
:type client: :class:`~kazoo.client.KazooClient`
:param path: The lock path to use. May not contain the strings
``__SHARED__`` or ``__EXCLUSIVE__``, as they are used
internally
:type path: str
:param identifier: Name to use for this lock contender, which may be
useful for querying to see who the current lock
:py:meth:`contenders` are. May not contain the
string ``__UNLOCK__``, as this is used internally.
:type identifier: str
:param exclusive: Whether this is an exclusive lock (``False`` means
a "shared lock" as described above)
:type exclusive: bool
.. versionadded:: 1.4
The exclusive option.
"""
if self._MODE_SHARED in path or self._MODE_EXCLUSIVE in path:
raise ValueError('Path "{}" contains a reserved word'.format(path))
if identifier and self._UNLOCK_REQUEST in str(identifier):
raise ValueError('Identifier "{}" contains a reserved word'.format(
identifier))
self.client = client
self.path = path
self.exclusive = exclusive
# some data is written to the node. this can be queried via
# contenders() to see who is contending for the lock
self.data = str(identifier or "").encode('utf-8')
self.wake_event = client.handler.event_object()
mode_suffix = self._MODE_EXCLUSIVE if exclusive else self._MODE_SHARED
# props to Netflix Curator for this trick. It is possible for our
# create request to succeed on the server, but for a failure to
# prevent us from getting back the full path name. We prefix our
# lock name with a uuid and can check for its presence on retry.
self.prefix = uuid.uuid4().hex + mode_suffix
self.create_path = self.path + "/" + self.prefix
self.create_tried = False
self.is_acquired = False
self.assured_path = False
self.cancelled = False
self._retry = KazooRetry(max_tries=None)
示例7: __init__
def __init__(self, host='127.0.0.1:2181', lock_path_prefix='/mastermind/locks/'):
self.client = KazooClient(host, timeout=3)
logger.info('Connecting to zookeeper host {0}, '
'lock_path_prefix: {1}'.format(host, lock_path_prefix))
try:
self.client.start()
except Exception as e:
logger.error(e)
raise
self._retry = KazooRetry(max_tries=self.RETRIES)
self.lock_path_prefix = lock_path_prefix
示例8: __init__
def __init__(self, module, server_list, host_ip, logging_fn=None, zk_timeout=400,
log_response_time=None):
self.host_ip = host_ip
# logging
logger = logging.getLogger(module)
logger.setLevel(logging.DEBUG)
try:
handler = logging.handlers.RotatingFileHandler(
LOG_DIR + module + '-zk.log', maxBytes=10*1024*1024, backupCount=5)
except IOError:
print "Cannot open log file in %s" %(LOG_DIR)
else:
log_format = logging.Formatter('%(asctime)s [%(name)s]: %(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
handler.setFormatter(log_format)
logger.addHandler(handler)
if logging_fn:
self.log = logging_fn
else:
self.log = self.syslog
self.log_response_time = log_response_time
# KazooRetry to retry keeper CRUD operations
self._retry = KazooRetry(max_tries=None, max_delay=300,
sleep_func=gevent.sleep)
self._zk_client = kazoo.client.KazooClient(
server_list,
timeout=zk_timeout,
handler=kazoo.handlers.gevent.SequentialGeventHandler(),
logger=logger,
connection_retry=self._retry,
command_retry=self._retry)
self._zk_client.add_listener(self._zk_listener)
self._logger = logger
self._election = None
self._server_list = server_list
self._conn_state = None
self._sandesh_connection_info_update(status='INIT', message='')
self._lost_cb = None
self._suspend_cb = None
self.delete_node = self._response_time(self.delete_node, "DELETE")
self.create_node = self._response_time(self.create_node, "CREATE")
self.read_node = self._response_time(self.read_node, "READ")
self.get_children= self._response_time(self.get_children, "GET_CHILDREN")
self.exists = self._response_time(self.exists, "EXISTS")
self.connect()
示例9: __init__
def __init__(self, client, path, identifier=None, node_name="__lock__",
exclude_names=None):
"""Create a Kazoo lock.
node_name and exclude_names are typically only used internally to
implement read/write locks. They should be left unset for exclusive
locks.
:param client: A :class:`~kazoo.client.KazooClient` instance.
:param path: The lock path to use.
:param identifier: Name to use for this lock contender. This
can be useful for querying to see who the
current lock contenders are.
:param node_name: Node name, after the contender UUID, before the
sequence number. Involved in read/write locks. For a
normal (exclusive) lock, leave unset.
:param exclude_names: Node names which exclude this contender when
present at a lower sequence number. Involved in
read/write locks. For a normal (exclusive) lock,
leave unset.
"""
self.client = client
self.path = path
# some data is written to the node. this can be queried via
# contenders() to see who is contending for the lock
self.data = str(identifier or "").encode('utf-8')
self.wake_event = client.handler.event_object()
self.node_name = node_name
if exclude_names is None:
exclude_names = [self.node_name]
self.exclude_names = exclude_names
# props to Netflix Curator for this trick. It is possible for our
# create request to succeed on the server, but for a failure to
# prevent us from getting back the full path name. We prefix our
# lock name with a uuid and can check for its presence on retry.
self.prefix = uuid.uuid4().hex + self.node_name
self.create_path = self.path + "/" + self.prefix
self.create_tried = False
self.is_acquired = False
self.assured_path = False
self.cancelled = False
self._retry = KazooRetry(max_tries=None,
sleep_func=client.handler.sleep_func)
示例10: __init__
def __init__(self,server_list):
self._retry = KazooRetry(max_tries=None, max_delay=300,
sleep_func=gevent.sleep)
self._zk_client = kazoo.client.KazooClient(
server_list,
timeout=400,
handler=kazoo.handlers.gevent.SequentialGeventHandler(),
connection_retry=self._retry,
command_retry=self._retry)
self._zk_client.add_listener(self._zk_listener)
self._election = None
self._server_list = server_list
self._conn_state = None
self._lost_cb = None
self.connect()
示例11: __init__
def __init__(self, module, server_list, logging_fn=None):
# logging
logger = logging.getLogger(module)
logger.setLevel(logging.INFO)
try:
handler = logging.handlers.RotatingFileHandler(LOG_DIR + module + '-zk.log', maxBytes=10*1024*1024, backupCount=5)
except IOError:
print "Cannot open log file in %s" %(LOG_DIR)
else:
log_format = logging.Formatter('%(asctime)s [%(name)s]: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
handler.setFormatter(log_format)
logger.addHandler(handler)
if logging_fn:
self.log = logging_fn
else:
self.log = self.syslog
self._zk_client = \
kazoo.client.KazooClient(
server_list,
timeout=400,
handler=kazoo.handlers.gevent.SequentialGeventHandler(),
logger=logger)
self._zk_client.add_listener(self._zk_listener)
self._logger = logger
self._election = None
self._server_list = server_list
# KazooRetry to retry keeper CRUD operations
self._retry = KazooRetry(max_tries=None, max_delay=300,
sleep_func=gevent.sleep)
self._conn_state = None
self._sandesh_connection_info_update(status='INIT', message='')
self._lost_cb = None
self.connect()
示例12: __init__
#.........这里部分代码省略.........
self.handler = handler if handler else SequentialThreadingHandler()
if inspect.isclass(self.handler):
raise ConfigurationError("Handler must be an instance of a class, "
"not the class: %s" % self.handler)
self.auth_data = auth_data if auth_data else set([])
self.default_acl = default_acl
self.randomize_hosts = randomize_hosts
self.hosts, chroot = collect_hosts(hosts, randomize_hosts)
if chroot:
self.chroot = normpath(chroot)
else:
self.chroot = ''
# Curator like simplified state tracking, and listeners for
# state transitions
self._state = KeeperState.CLOSED
self.state = KazooState.LOST
self.state_listeners = set()
self._reset()
self.read_only = read_only
if client_id:
self._session_id = client_id[0]
self._session_passwd = client_id[1]
else:
self._reset_session()
# ZK uses milliseconds
self._session_timeout = int(timeout * 1000)
# We use events like twitter's client to track current and
# desired state (connected, and whether to shutdown)
self._live = self.handler.async_result()
self._live.set(False)
self._writer_stopped = self.handler.event_object()
self._stopped = self.handler.event_object()
self._stopped.set()
self._writer_stopped.set()
if retry is not None:
self.retry = retry
assert self.handler.sleep_func == self.retry.sleep_func, \
'retry handler and event handler must use the same sleep func'
else:
retry_keys = dict(_RETRY_COMPAT_DEFAULTS)
for key in retry_keys:
try:
retry_keys[key] = kwargs.pop(key)
warnings.warn('Passing retry configuration param %s to the'
' client directly is deprecated, please pass a'
' configured retry object (using param %s)' % (
key, _RETRY_COMPAT_MAPPING[key]),
DeprecationWarning, stacklevel=2)
except KeyError:
pass
retry_keys = {_RETRY_COMPAT_MAPPING[oldname]: value for oldname, value in retry_keys.items()}
self.retry = KazooRetry(
sleep_func=self.handler.sleep_func,
**retry_keys)
self._connection = ConnectionHandler(
self, self.retry.copy(),
logger=self.logger)
# convenience API
from kazoo.recipe.barrier import Barrier
from kazoo.recipe.barrier import DoubleBarrier
from kazoo.recipe.counter import Counter
from kazoo.recipe.election import Election
from kazoo.recipe.lock import Lock
from kazoo.recipe.lock import Semaphore
from kazoo.recipe.partitioner import SetPartitioner
from kazoo.recipe.party import Party
from kazoo.recipe.party import ShallowParty
from kazoo.recipe.queue import Queue
from kazoo.recipe.queue import LockingQueue
from kazoo.recipe.watchers import ChildrenWatch
from kazoo.recipe.watchers import DataWatch
self.Barrier = partial(Barrier, self)
self.Counter = partial(Counter, self)
self.DoubleBarrier = partial(DoubleBarrier, self)
self.ChildrenWatch = partial(ChildrenWatch, self)
self.DataWatch = partial(DataWatch, self)
self.Election = partial(Election, self)
self.Lock = partial(Lock, self)
self.Party = partial(Party, self)
self.Queue = partial(Queue, self)
self.LockingQueue = partial(LockingQueue, self)
self.SetPartitioner = partial(SetPartitioner, self)
self.Semaphore = partial(Semaphore, self)
self.ShallowParty = partial(ShallowParty, self)
# If we got any unhandled keywords, complain like python would
if kwargs:
raise TypeError('__init__() got unexpected keyword arguments: %s' % (kwargs.keys(),))
示例13: Lock
class Lock(object):
"""Kazoo Lock
Example usage with a :class:`~kazoo.client.KazooClient` instance:
.. code-block:: python
zk = KazooClient()
zk.start()
lock = zk.Lock("/lockpath", "my-identifier")
with lock: # blocks waiting for lock acquisition
# do something with the lock
Note: This lock is not *re-entrant*. Repeated calls after already
acquired will block.
"""
_NODE_NAME = "__lock__"
def __init__(self, client, path, identifier=None):
"""Create a Kazoo lock.
:param client: A :class:`~kazoo.client.KazooClient` instance.
:param path: The lock path to use.
:param identifier: Name to use for this lock contender. This
can be useful for querying to see who the
current lock contenders are.
"""
self.client = client
self.path = path
# some data is written to the node. this can be queried via
# contenders() to see who is contending for the lock
self.data = str(identifier or "").encode("utf-8")
self.wake_event = client.handler.event_object()
# props to Netflix Curator for this trick. It is possible for our
# create request to succeed on the server, but for a failure to
# prevent us from getting back the full path name. We prefix our
# lock name with a uuid and can check for its presence on retry.
self.prefix = uuid.uuid4().hex + self._NODE_NAME
self.create_path = self.path + "/" + self.prefix
self.create_tried = False
self.is_acquired = False
self.assured_path = False
self.cancelled = False
self._retry = KazooRetry(max_tries=None, sleep_func=client.handler.sleep_func)
self._lock = client.handler.lock_object()
def _ensure_path(self):
self.client.ensure_path(self.path)
self.assured_path = True
def cancel(self):
"""Cancel a pending lock acquire."""
self.cancelled = True
self.wake_event.set()
def acquire(self, blocking=True, timeout=None):
"""
Acquire the lock. By defaults blocks and waits forever.
:param blocking: Block until lock is obtained or return immediately.
:type blocking: bool
:param timeout: Don't wait forever to acquire the lock.
:type timeout: float or None
:returns: Was the lock acquired?
:rtype: bool
:raises: :exc:`~kazoo.exceptions.LockTimeout` if the lock
wasn't acquired within `timeout` seconds.
.. versionadded:: 1.1
The timeout option.
"""
def _acquire_lock():
got_it = self._lock.acquire(False)
if not got_it:
raise ForceRetryError()
return True
retry = self._retry.copy()
retry.deadline = timeout
# Ensure we are locked so that we avoid multiple threads in
# this acquistion routine at the same time...
locked = self._lock.acquire(False)
if not locked and not blocking:
return False
if not locked:
# Lock acquire doesn't take a timeout, so simulate it...
try:
locked = retry(_acquire_lock)
except RetryFailedError:
#.........这里部分代码省略.........
示例14: Lock
#.........这里部分代码省略.........
.. versionadded:: 1.4
The exclusive option.
"""
if self._MODE_SHARED in path or self._MODE_EXCLUSIVE in path:
raise ValueError('Path "{}" contains a reserved word'.format(path))
if identifier and self._UNLOCK_REQUEST in str(identifier):
raise ValueError('Identifier "{}" contains a reserved word'.format(
identifier))
self.client = client
self.path = path
self.exclusive = exclusive
# some data is written to the node. this can be queried via
# contenders() to see who is contending for the lock
self.data = str(identifier or "").encode('utf-8')
self.wake_event = client.handler.event_object()
mode_suffix = self._MODE_EXCLUSIVE if exclusive else self._MODE_SHARED
# props to Netflix Curator for this trick. It is possible for our
# create request to succeed on the server, but for a failure to
# prevent us from getting back the full path name. We prefix our
# lock name with a uuid and can check for its presence on retry.
self.prefix = uuid.uuid4().hex + mode_suffix
self.create_path = self.path + "/" + self.prefix
self.create_tried = False
self.is_acquired = False
self.assured_path = False
self.cancelled = False
self._retry = KazooRetry(max_tries=None)
def _ensure_path(self):
self.client.ensure_path(self.path)
self.assured_path = True
def cancel(self):
"""Cancel a pending lock acquire."""
self.cancelled = True
self.wake_event.set()
def acquire(self, blocking=True, timeout=None, revoke=False, unlock=None):
"""
Acquire the lock. By defaults blocks and waits forever.
:param blocking: Block until lock is obtained or return immediately.
:type blocking: bool
:param timeout: Don't wait forever to acquire the lock.
:type timeout: float or None
:param revoke: Identify all existing locks and lock requests that
prevent this lock being acquired and immediately request
them to unlock (this does not mean they will unlock or
are even listening for such requests though)
:type revoke: bool
:param unlock: The callback which will be invoked exactly once if
another lock used ``revoke=True`` and this lock or lock
request is blocking that lock from being acquired (it is
legal to use ``None`` to ignore revocation requests, or
provide a callback which takes no action)
:type unlock: a zero-parameter function
:returns: Was the lock acquired?
:rtype: bool
示例15: KazooClient
class KazooClient(object):
"""An Apache Zookeeper Python client supporting alternate callback
handlers and high-level functionality.
Watch functions registered with this class will not get session
events, unlike the default Zookeeper watches. They will also be
called with a single argument, a
:class:`~kazoo.protocol.states.WatchedEvent` instance.
"""
def __init__(self, hosts='127.0.0.1:2181',
timeout=10.0, client_id=None, handler=None,
default_acl=None, auth_data=None, read_only=None,
randomize_hosts=True, connection_retry=None,
command_retry=None, logger=None, **kwargs):
"""Create a :class:`KazooClient` instance. All time arguments
are in seconds.
:param hosts: Comma-separated list of hosts to connect to
(e.g. 127.0.0.1:2181,127.0.0.1:2182,[::1]:2183).
:param timeout: The longest to wait for a Zookeeper connection.
:param client_id: A Zookeeper client id, used when
re-establishing a prior session connection.
:param handler: An instance of a class implementing the
:class:`~kazoo.interfaces.IHandler` interface
for callback handling.
:param default_acl: A default ACL used on node creation.
:param auth_data:
A list of authentication credentials to use for the
connection. Should be a list of (scheme, credential)
tuples as :meth:`add_auth` takes.
:param read_only: Allow connections to read only servers.
:param randomize_hosts: By default randomize host selection.
:param connection_retry:
A :class:`kazoo.retry.KazooRetry` object to use for
retrying the connection to Zookeeper. Also can be a dict of
options which will be used for creating one.
:param command_retry:
A :class:`kazoo.retry.KazooRetry` object to use for
the :meth:`KazooClient.retry` method. Also can be a dict of
options which will be used for creating one.
:param logger: A custom logger to use instead of the module
global `log` instance.
Basic Example:
.. code-block:: python
zk = KazooClient()
zk.start()
children = zk.get_children('/')
zk.stop()
As a convenience all recipe classes are available as attributes
and get automatically bound to the client. For example::
zk = KazooClient()
zk.start()
lock = zk.Lock('/lock_path')
.. versionadded:: 0.6
The read_only option. Requires Zookeeper 3.4+
.. versionadded:: 0.6
The retry_max_delay option.
.. versionadded:: 0.6
The randomize_hosts option.
.. versionchanged:: 0.8
Removed the unused watcher argument (was second argument).
.. versionadded:: 1.2
The connection_retry, command_retry and logger options.
"""
self.logger = logger or log
# Record the handler strategy used
self.handler = handler if handler else SequentialThreadingHandler()
if inspect.isclass(self.handler):
raise ConfigurationError("Handler must be an instance of a class, "
"not the class: %s" % self.handler)
self.auth_data = auth_data if auth_data else set([])
self.default_acl = default_acl
self.randomize_hosts = randomize_hosts
self.hosts = None
self.chroot = None
self.set_hosts(hosts)
# Curator like simplified state tracking, and listeners for
# state transitions
self._state = KeeperState.CLOSED
self.state = KazooState.LOST
self.state_listeners = set()
self._reset()
self.read_only = read_only
#.........这里部分代码省略.........