def test_ipv6(self): hosts, chroot = collect_hosts('[fe80::200:5aee:feaa:20a2]:2181') self.assertEquals([('fe80::200:5aee:feaa:20a2', 2181)], hosts) self.assertEquals(None, chroot) hosts, chroot = collect_hosts(['[fe80::200:5aee:feaa:20a2]:2181']) self.assertEquals([('fe80::200:5aee:feaa:20a2', 2181)], hosts) self.assertEquals(None, chroot)
def test_ipv4(self): hosts, chroot = collect_hosts('127.0.0.1:2181, 192.168.1.2:2181, \ 132.254.111.10:2181') self.assertEquals([('127.0.0.1', 2181), ('192.168.1.2', 2181), ('132.254.111.10', 2181)], hosts) self.assertEquals(None, chroot) hosts, chroot = collect_hosts(['127.0.0.1:2181', '192.168.1.2:2181', '132.254.111.10:2181']) self.assertEquals([('127.0.0.1', 2181), ('192.168.1.2', 2181), ('132.254.111.10', 2181)], hosts) self.assertEquals(None, chroot)
def test_hosts_list(self): hosts, chroot = collect_hosts('zk01:2181, zk02:2181, zk03:2181') expected1 = [('zk01', 2181), ('zk02', 2181), ('zk03', 2181)] self.assertEquals(expected1, hosts) self.assertEquals(None, chroot) hosts, chroot = collect_hosts(['zk01:2181', 'zk02:2181', 'zk03:2181']) self.assertEquals(expected1, hosts) self.assertEquals(None, chroot) expected2 = '/test' hosts, chroot = collect_hosts('zk01:2181, zk02:2181, zk03:2181/test') self.assertEquals(expected1, hosts) self.assertEquals(expected2, chroot) hosts, chroot = collect_hosts(['zk01:2181', 'zk02:2181', 'zk03:2181', '/test']) self.assertEquals(expected1, hosts) self.assertEquals(expected2, chroot)
def set_hosts(self, hosts, randomize_hosts=None): """ sets the list of hosts used by this client. This function accepts the same format hosts parameter as the init function and sets the client to use the new hosts the next time it needs to look up a set of hosts. This function does not affect the current connected status. It is not currently possible to change the chroot with this function, setting a host list with a new chroot will raise a ConfigurationError. :param hosts: see description in :meth:`KazooClient.__init__` :param randomize_hosts: override client default for host randomization :raises: :exc:`ConfigurationError` if the hosts argument changes the chroot .. versionadded:: 1.4 .. warning:: Using this function to point a client to a completely disparate zookeeper server cluster has undefined behavior. """ if randomize_hosts is None: randomize_hosts = self.randomize_hosts self.hosts, chroot = collect_hosts(hosts, randomize_hosts) if chroot: new_chroot = normpath(chroot) else: new_chroot = '' if self.chroot is not None and new_chroot != self.chroot: raise ConfigurationError("Changing chroot at runtime is not " "currently supported") self.chroot = new_chroot
def __init__(self, hosts='127.0.0.1:2181', watcher=None, timeout=10.0, client_id=None, max_retries=None, retry_delay=0.1, retry_backoff=2, retry_jitter=0.8, handler=None, default_acl=None, auth_data=None, read_only=None): """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). :param watcher: Set a default watcher. This will be called by the actual default watcher that :class:`KazooClient` establishes. :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 max_retries: Maximum retries when using the :meth:`KazooClient.retry` method. :param retry_delay: Initial delay when retrying a call. :param retry_backoff: Backoff multiplier between retry attempts. Defaults to 2 for exponential back-off. :param retry_jitter: How much jitter delay to introduce per call. An amount of time up to this will be added per retry call to avoid hammering the server. :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. Retry parameters will be used for connection establishment attempts and reconnects. 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') """ self.log_debug = logging.DEBUG >= log.getEffectiveLevel() # 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.hosts, chroot = collect_hosts(hosts) if chroot: self.chroot = normpath(chroot) else: self.chroot = '' # Curator like simplified state tracking, and listeners for # state transitions self._state_lock = self.handler.rlock_object() 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._session_id = None self._session_passwd = str(bytearray([0] * 16)) # 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.event_object() self._writer_stopped = self.handler.event_object() self._stopped = self.handler.event_object() self._stopped.set() self._writer_stopped.set() self.retry = KazooRetry( max_tries=max_retries, delay=retry_delay, backoff=retry_backoff, max_jitter=retry_jitter, sleep_func=self.handler.sleep_func ) self.retry_sleeper = self.retry.retry_sleeper.copy() self._connection = ConnectionHandler( self, self.retry.retry_sleeper.copy(), log_debug=self.log_debug) # convenience API from kazoo.recipe.barrier import Barrier from kazoo.recipe.barrier import DoubleBarrier from kazoo.recipe.election import Election from kazoo.recipe.lock import Lock from kazoo.recipe.partitioner import SetPartitioner from kazoo.recipe.party import Party from kazoo.recipe.party import ShallowParty from kazoo.recipe.watchers import ChildrenWatch from kazoo.recipe.watchers import DataWatch self.Barrier = partial(Barrier, 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.SetPartitioner = partial(SetPartitioner, self) self.ShallowParty = partial(ShallowParty, self)
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, 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.event_object() self._writer_stopped = self.handler.event_object() self._stopped = self.handler.event_object() self._stopped.set() self._writer_stopped.set() self.retry = self._conn_retry = None if connection_retry is not None: self._conn_retry = connection_retry if self.handler.sleep_func != self._conn_retry.sleep_func: raise ConfigurationError("Retry handler and event handler " " must use the same sleep func") if command_retry is not None: self.retry = command_retry if self.handler.sleep_func != self.comand_retry.sleep_func: raise ConfigurationError("Command retry handler and event handler " " must use the same sleep func") if self.retry is None or self._conn_retry is None: old_retry_keys = dict(_RETRY_COMPAT_DEFAULTS) for key in old_retry_keys: try: old_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 = {} for oldname, value in old_retry_keys.items(): retry_keys[_RETRY_COMPAT_MAPPING[oldname]] = value if self._conn_retry is None: self._conn_retry = KazooRetry( sleep_func=self.handler.sleep_func, **retry_keys) if self.retry is None: self.retry = KazooRetry( sleep_func=self.handler.sleep_func, **retry_keys) self._conn_retry.interrupt = lambda: self._stopped.is_set() self._connection = ConnectionHandler(self, self._conn_retry.copy(), logger=self.logger) 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(),))
def __init__(self, hosts='127.0.0.1:2181', timeout=10.0, client_id=None, max_retries=None, retry_delay=0.1, retry_backoff=2, retry_jitter=0.8, retry_max_delay=3600, handler=None, default_acl=None, auth_data=None, read_only=None, randomize_hosts=True): """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). :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 max_retries: Maximum retries when using the :meth:`KazooClient.retry` method. :param retry_delay: Initial delay when retrying a call. :param retry_backoff: Backoff multiplier between retry attempts. Defaults to 2 for exponential back-off. :param retry_jitter: How much jitter delay to introduce per call. An amount of time up to this will be added per retry call to avoid hammering the server. :param retry_max_delay: Maximum delay in seconds, regardless of other backoff settings. Defaults to one hour. :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. Retry parameters will be used for connection establishment attempts and reconnects. 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). """ self.log_debug = logging.DEBUG >= log.getEffectiveLevel() # 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, 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_lock = self.handler.rlock_object() 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._session_id = None self._session_passwd = b'\x00' * 16 # 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.event_object() self._writer_stopped = self.handler.event_object() self._stopped = self.handler.event_object() self._stopped.set() self._writer_stopped.set() self.retry = KazooRetry(max_tries=max_retries, delay=retry_delay, backoff=retry_backoff, max_jitter=retry_jitter, max_delay=retry_max_delay, sleep_func=self.handler.sleep_func) self.retry_sleeper = self.retry.retry_sleeper.copy() self._connection = ConnectionHandler(self, self.retry.retry_sleeper.copy(), log_debug=self.log_debug) # 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.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.SetPartitioner = partial(SetPartitioner, self) self.Semaphore = partial(Semaphore, self) self.ShallowParty = partial(ShallowParty, self)