def test_shard_id_registers(self): ss1 = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH) ss2 = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH) ss1.join(self.INSTANCE1, shard=0) ss2.join(self.INSTANCE2, shard=1) assert list(ss1) == [ServiceInstance(self.INSTANCE1, shard=0), ServiceInstance(self.INSTANCE2, shard=1)] assert list(ss2) == [ServiceInstance(self.INSTANCE1, shard=0), ServiceInstance(self.INSTANCE2, shard=1)]
def test_async_client_iteration(self): ss1 = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH) ss2 = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH) ss1.join(self.INSTANCE1) ss2.join(self.INSTANCE2) assert list(ss1) == [ServiceInstance(self.INSTANCE1), ServiceInstance(self.INSTANCE2)] assert list(ss2) == [ServiceInstance(self.INSTANCE1), ServiceInstance(self.INSTANCE2)]
def test_canceled_join_long_time(self): zk = self.make_zk(self._server.ensemble) zk.live.wait() session_id = self.session_id(zk) ss = ServerSet(zk, self.SERVICE_PATH) join_signal = threading.Event() memberships = [] def on_expire(): pass def do_join(): memberships.append(ss.join(self.INSTANCE1, expire_callback=on_expire)) class JoinThread(threading.Thread): def run(_): while True: join_signal.wait() join_signal.clear() do_join() joiner = JoinThread() joiner.daemon = True joiner.start() do_join() assert len(memberships) == 1 and memberships[0] is not Membership.error() self._server.expire(session_id) self._server.shutdown() join_signal.set() self._server.start() while len(memberships) == 1: time.sleep(0.1) assert len(memberships) == 2 and memberships[1] is not Membership.error()
def test_client_iteration(self): ss = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH) assert list(ss) == [] ss.join(self.INSTANCE1) assert list(ss) == [ServiceInstance(self.INSTANCE1)] ss.join(self.INSTANCE2) assert list(ss) == [ServiceInstance(self.INSTANCE1), ServiceInstance(self.INSTANCE2)]
def get_scheduler_serverset(cls, cluster, port=2181, verbose=False, **kw): if cluster.zk is None: raise ValueError('Cluster has no associated zookeeper ensemble!') if cluster.scheduler_zk_path is None: raise ValueError('Cluster has no defined scheduler path, must specify scheduler_zk_path ' 'in your cluster config!') hosts = [h + ':{p}' for h in cluster.zk.split(',')] zk = TwitterKazooClient.make(str(','.join(hosts).format(p=port)), verbose=verbose) return zk, ServerSet(zk, cluster.scheduler_zk_path, **kw)
def make_serverset(self, assigned_task): role, environment, name = (assigned_task.task.owner.role, assigned_task.task.environment, assigned_task.task.jobName) path = posixpath.join(self.__root, role, environment, name) client = KazooClient(self.__ensemble, connection_retry=self.DEFAULT_RETRY_POLICY) client.start() return ServerSet(client, path)
def get_scheduler_serverset(cls, cluster, port=2181, verbose=False, **kw): if cluster.zk is None: raise ValueError('Cluster has no associated zookeeper ensemble!') if cluster.scheduler_zk_path is None: raise ValueError( 'Cluster has no defined scheduler path, must specify scheduler_zk_path ' 'in your cluster config!') zk = TwitterKazooClient.make(str('%s:%s' % (cluster.zk, port)), verbose=verbose) return zk, ServerSet(zk, cluster.scheduler_zk_path, **kw)
def __init__(self, client, path, timeout_secs, endpoint, additional=None, shard=None, name=None): self.__client = client self.__connect_event = client.start_async() self.__timeout_secs = timeout_secs self.__announcer = Announcer(ServerSet(client, path), endpoint, additional=additional, shard=shard) self.__name = name or self.DEFAULT_NAME self.__status = None self.start_event = threading.Event() self.metrics.register(LambdaGauge('disconnected_time', self.__announcer.disconnected_time))
def test_client_watcher(self): canceled_endpoints = [] canceled = threading.Event() joined_endpoints = [] joined = threading.Event() def on_join(endpoint): joined_endpoints[:] = [endpoint] joined.set() def on_leave(endpoint): canceled_endpoints[:] = [endpoint] canceled.set() service1 = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH, on_join=on_join, on_leave=on_leave) service2 = ServerSet(self.make_zk(self._server.ensemble), self.SERVICE_PATH) member1 = service2.join(self.INSTANCE1) joined.wait(2.0) assert joined.is_set() assert not canceled.is_set() assert joined_endpoints == [ServiceInstance(self.INSTANCE1)] joined.clear() service2.join(self.INSTANCE2) joined.wait(2.0) assert joined.is_set() assert not canceled.is_set() assert joined_endpoints == [ServiceInstance(self.INSTANCE2)] joined.clear() service2.cancel(member1) canceled.wait(2.0) assert canceled.is_set() assert not joined.is_set() assert canceled_endpoints == [ServiceInstance(self.INSTANCE1)] canceled.clear()
def main(args): if len(args) != 1: app.error('Must supply a serverset path to monitor.') def on_join(endpoint): print('@ %s += %s' % (datetime.now(), endpoint)) def on_leave(endpoint): print('@ %s -= %s' % (datetime.now(), endpoint)) ss = ServerSet(ZooKeeper(), args[0], on_join=on_join, on_leave=on_leave) while True: time.sleep(100)
def _construct_serverset(self, options): import socket import threading import zookeeper from twitter.common.zookeeper.client import ZooKeeper from twitter.common.zookeeper.serverset import Endpoint, ServerSet log.debug('ServerSet module constructing serverset.') hostname = socket.gethostname() primary_port = int(options.serverset_module_primary_port) primary = Endpoint(hostname, primary_port) additional = dict((port_name, Endpoint(hostname, port_number)) for port_name, port_number in options.serverset_module_extra.items()) # TODO(wickman) Add timeout parameterization here. self._zookeeper = ZooKeeper(options.serverset_module_ensemble) self._serverset = ServerSet(self._zookeeper, options.serverset_module_path) self._join_args = (primary, additional)