class Client(object): """ Do autodiscovery for ElastiCache memcache cluster. """ def __init__(self, client_cls, endpoint, autodiscovery=True, autodiscovery_timeout=10, autodiscovery_interval=60, *args, **kwargs): self.client_cls = client_cls self.endpoint = endpoint self.autodiscovery = autodiscovery self.autodiscovery_timeout = autodiscovery_timeout self.args = args self.kwargs = kwargs self.cluster = Cluster(self.endpoint, self.autodiscovery_timeout) if self.cluster.servers: self.client = self.client_cls(self.cluster.servers, *self.args, **self.kwargs) ec_logger.info('Cluster nodes are %s', self.cluster.servers) else: self.client = None ec_logger.warn('Cluster nodes are empty, :(') self.need_update = False self.update_lock = Lock() if self.autodiscovery: self.timer = Timer('AutoDiscovery', autodiscovery_interval, self.detect_cluster) self.timer.start() else: self.timer = None def __del__(self): pass def __getattr__(self, key): if not hasattr(self.client, key): msg = "'%s' obj has no attribute '%s'" % (type(self).__name__, key) raise AttributeError(msg) client_func = getattr(self.client, key) def exec_func(self, *args, **kwargs): if self.need_update: ec_logger.info('Cluster nodes are: %s', self.cluster.servers) self.client = self.client_cls(self.cluster.servers, *self.args, **self.kwargs) self.need_update = False return client_func(*args, **kwargs) exec_func.__name__ = key return MethodType(exec_func, self) def detect_cluster(self): try: cluster = Cluster(self.endpoint, self.autodiscovery_timeout) except Exception, e: ec_logger.exception(traceback.format_exc()) return if self.cluster.version != cluster.version: self.cluster = cluster self.need_update = True
class TestTimer(unittest.TestCase): def setUp(self): self.mock_func = Mock() def tearDown(self): pass def test_run_timer(self): self.timer = Timer('test_timer', 1, self.mock_func) self.timer.start() time.sleep(3) self.assertTrue(self.mock_func.call_count >= 2) self.timer.stop() self.timer.join() self.assertTrue(self.timer.isAlive() == False) def test_args(self): self.timer = Timer('test_timer', 1, self.mock_func, args=[1, 2]) self.timer.start() time.sleep(2) self.mock_func.assert_called_with(1, 2) self.timer.stop() self.timer.join() self.assertTrue(self.timer.isAlive() == False) def test_kwargs(self): self.timer = Timer('test_timer', 1, self.mock_func, kwargs={'arg1': 3, 'arg2': 'foo'}) self.timer.start() time.sleep(2) self.mock_func.assert_called_with(arg1=3, arg2='foo') self.timer.stop() self.timer.join() self.assertTrue(self.timer.isAlive() == False)