Exemplo n.º 1
0
    def __init__(self,
                 endpoint,
                 autodiscovery_timeout=10,
                 autodiscovery_interval=60,
                 *args,
                 **kwargs):
        """
        Create a new Client object, and launch a timer for the object.

        @param endpoint: String
        something like: test.lwgyhw.cfg.usw2.cache.amazonaws.com:11211

        @autodiscovery_timeout: Number
        Secondes for socket connection timeout when do autodiscovery

        @autodiscovery_interval: Number
        Seconds interval for check cluster status

        @client_debug: String
        A file name, if set, will write debug message to that file

        All Other parameters will be passed to python-memcached
        """
        self.endpoint = endpoint
        self.autodiscovery_timeout = autodiscovery_timeout
        elasticache_logger.debug('endpoint: %s' % endpoint)
        self.cluster = Cluster(endpoint, autodiscovery_timeout)
        self.ring = MemcacheRing(self.cluster.servers, *args, **kwargs)
        self.need_update = False
        self.lock = Lock()

        self.timer = RepeatTimer('autodiscovery', autodiscovery_interval,
                                 self._update)
        self.timer.start()
class TestRepeatTimer(unittest.TestCase):
    def setUp(self):
        self.mock_func = Mock()

    def test_run_timer(self):
        self.timer = RepeatTimer('test_timer', 1, self.mock_func)
        self.timer.start()
        time.sleep(3)
        self.assertTrue(self.mock_func.call_count >= 2)

    def test_args(self):
        self.timer = RepeatTimer('test_timer', 1, self.mock_func, args=[1, 2])
        self.timer.start()
        time.sleep(2)
        self.mock_func.assert_called_with(1, 2)

    def test_kwargs(self):
        self.timer = RepeatTimer('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')

    def tearDown(self):
        self.timer.stop_timer()
        self.timer.join()
class MemcacheClient():
    """
    Do autodiscovery for elasticache memcache cluster.
    """

    def __init__(self, endpoint, autodiscovery_timeout=10, autodiscovery_interval=60, *args, **kwargs):
        """
        Create a new Client object, and launch a timer for the object.

        @param endpoint: String
        something like: test.lwgyhw.cfg.usw2.cache.amazonaws.com:11211

        @autodiscovery_timeout: Number
        Secondes for socket connection timeout when do autodiscovery

        @autodiscovery_interval: Number
        Seconds interval for check cluster status

        @client_debug: String
        A file name, if set, will write debug message to that file

        All Other parameters will be passed to python-memcached
        """
        self.endpoint = endpoint
        self.autodiscovery_timeout = autodiscovery_timeout
        elasticache_logger.debug('endpoint: %s' % endpoint)
        self.cluster = Cluster(endpoint, autodiscovery_timeout)
        self.ring = MemcacheRing(self.cluster.servers, *args, **kwargs)
        self.need_update = False
        self.lock = Lock()

        self.timer = RepeatTimer('autodiscovery', autodiscovery_interval, self._update)
        self.timer.start()

    def __getattr__(self, key):
        if not hasattr(self.ring, key):
            msg = "'%s' object has no attribute '%s'" % (type(self).__name__, key)
            raise AttributeError(msg)
        ori_func = getattr(self.ring, key)
        def tmp_func(self, *args, **kwargs):
            self.lock.acquire(True)
            if self.need_update:
                self.ring.set_servers(self.cluster.servers)
                self.need_update = False
            self.lock.release()
            return ori_func(*args, **kwargs)
        tmp_func.__name__ = key
        return MethodType(tmp_func, self)

    def _update(self):
        try:
            cluster = Cluster(self.endpoint, self.autodiscovery_timeout)
        except Exception, e:
            elasticache_logger.debug(e)
            return
        if cluster.version != self.cluster.version:
            self.lock.acquire(True)
            self.cluster = cluster
            self.need_update = True
            self.lock.release()
 def test_kwargs(self):
     self.timer = RepeatTimer('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')
    def __init__(self, endpoint, autodiscovery_timeout=10, autodiscovery_interval=60, *args, **kwargs):
        """
        Create a new Client object, and launch a timer for the object.

        @param endpoint: String
        something like: test.lwgyhw.cfg.usw2.cache.amazonaws.com:11211

        @autodiscovery_timeout: Number
        Secondes for socket connection timeout when do autodiscovery

        @autodiscovery_interval: Number
        Seconds interval for check cluster status

        @client_debug: String
        A file name, if set, will write debug message to that file

        All Other parameters will be passed to python-memcached
        """
        self.endpoint = endpoint
        self.autodiscovery_timeout = autodiscovery_timeout
        elasticache_logger.debug("endpoint: %s" % endpoint)
        self.cluster = Cluster(endpoint, autodiscovery_timeout)
        self.ring = MemcacheRing(self.cluster.servers, *args, **kwargs)
        self.need_update = False
        self.lock = Lock()

        self.timer = RepeatTimer("autodiscovery", autodiscovery_interval, self._update)
        self.timer.start()
class TestRepeatTimer(unittest.TestCase):
    def setUp(self):
        self.mock_func = Mock()
    def test_run_timer(self):
        self.timer = RepeatTimer('test_timer', 1, self.mock_func)
        self.timer.start()
        time.sleep(3)
        self.assertTrue(self.mock_func.call_count >= 2)
    def test_args(self):
        self.timer = RepeatTimer('test_timer', 1, self.mock_func, args=[1,2])
        self.timer.start()
        time.sleep(2)
        self.mock_func.assert_called_with(1, 2)
    def test_kwargs(self):
        self.timer = RepeatTimer('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')
    def tearDown(self):
        self.timer.stop_timer()
        self.timer.join()
    def __init__(
            self, endpoint, ad_timeout=10, ad_interval=60, *args, **kwargs):
        """
        Create a new Client object, and launch a timer for auto discovery

        :param endpoint: String
        something like: test.lwgyhw.cfg.usw2.cache.amazonaws.com:11211

        :param ad_timeout: Int
        socket connection timeout during auto discovery, in the unit of second

        :param ad_interval: Int
        auto discovery interval, the unit is second, in the unit of second

        All other parameters will be passed to python-memcached
        """
        self.endpoint = endpoint
        self.ad_timeout = ad_timeout
        cluster = Cluster(endpoint, ad_timeout)
        self.cluster = cluster
        self.wc = WrapperClient(cluster, *args, **kwargs)
        self.lock = threading.Lock()
        self.timer = RepeatTimer('autodiscovery', ad_interval, self._update)
        self.timer.start()
 def test_args(self):
     self.timer = RepeatTimer('test_timer', 1, self.mock_func, args=[1, 2])
     self.timer.start()
     time.sleep(2)
     self.mock_func.assert_called_with(1, 2)
 def test_run_timer(self):
     self.timer = RepeatTimer('test_timer', 1, self.mock_func)
     self.timer.start()
     time.sleep(3)
     self.assertTrue(self.mock_func.call_count >= 2)
class MemcacheClient(object):
    """
    Implement autodiscovery for elasticache memcache cluster
    """

    def __init__(
            self, endpoint, ad_timeout=10, ad_interval=60, *args, **kwargs):
        """
        Create a new Client object, and launch a timer for auto discovery

        :param endpoint: String
        something like: test.lwgyhw.cfg.usw2.cache.amazonaws.com:11211

        :param ad_timeout: Int
        socket connection timeout during auto discovery, in the unit of second

        :param ad_interval: Int
        auto discovery interval, the unit is second, in the unit of second

        All other parameters will be passed to python-memcached
        """
        self.endpoint = endpoint
        self.ad_timeout = ad_timeout
        cluster = Cluster(endpoint, ad_timeout)
        self.cluster = cluster
        self.wc = WrapperClient(cluster, *args, **kwargs)
        self.lock = threading.Lock()
        self.timer = RepeatTimer('autodiscovery', ad_interval, self._update)
        self.timer.start()

    def __getattr__(self, name):
        if not hasattr(memcache.Client, name):
            msg = 'no attribute %s' % name
            raise AttributeError(msg)
        with self.lock:
            func = getattr(self.wc, name)

            def wrapper(self, *args, **kwargs):
                return func(*args, **kwargs)

            wrapper.__name__ = name
            method_func = MethodType(wrapper, self)
            setattr(self, name, method_func)
            return method_func

    def _update(self):
        self.cluster.update()

    def stop_timer(self):
        """
        Every MemcacheClient will start a timer for auto discovery,
        if do not use MemcacheClient object anymore,
        please call this funciton to stop the timer,
        or the timer will run forever
        """
        self.timer.stop_timer()
        self.timer.join()

    def cluster_size(self):
        with self.cluster.lock:
            return len(self.cluster.servers)
 def test_kwargs(self):
     self.timer = RepeatTimer('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')
 def test_args(self):
     self.timer = RepeatTimer('test_timer', 1, self.mock_func, args=[1,2])
     self.timer.start()
     time.sleep(2)
     self.mock_func.assert_called_with(1, 2)
 def test_run_timer(self):
     self.timer = RepeatTimer('test_timer', 1, self.mock_func)
     self.timer.start()
     time.sleep(3)
     self.assertTrue(self.mock_func.call_count >= 2)