From 52a4477cbd25002e90ce3a0216e28a85013008ac Mon Sep 17 00:00:00 2001 From: svanellewee Date: Wed, 7 Nov 2018 10:10:23 +0200 Subject: [PATCH 1/2] gat implementation & flake8 update --- memcache.py | 72 +++++++++++++++++++++++++++++++++++++++++- tests/test_memcache.py | 11 +++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/memcache.py b/memcache.py index 05b6657..73b747c 100644 --- a/memcache.py +++ b/memcache.py @@ -1113,6 +1113,61 @@ def _unsafe_get(): server.mark_dead(msg) return None + def _gat(self, cmd, key, time, noreply=False): + key = self._encode_key(key) + if self.do_check_key: + self.check_key(key) + server, key = self._get_server(key) + if not server: + return None + + def _unsafe_gat(): + self._statlog(cmd) + try: + _time = str(time) + _time = _time.encode('utf-8') + cmd_bytes = cmd.encode('utf-8') if six.PY3 else cmd + fullcmd = b''.join((cmd_bytes, b' ', _time, b' ', key)) + server.send_cmd(fullcmd) + rkey = flags = rlen = cas_id = None + + if cmd == 'gats': + rkey, flags, rlen, cas_id, = self._expect_cas_value( + server, raise_exception=True + ) + if rkey and self.cache_cas: + self.cas_ids[rkey] = cas_id + else: + rkey, flags, rlen, = self._expectvalue( + server, raise_exception=True + ) + + if not rkey: + return None + try: + value = self._recv_value(server, flags, rlen) + finally: + server.expect(b"END", raise_exception=True) + except (_Error, socket.error) as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return None + + return value + + try: + return _unsafe_gat() + except _ConnectionDeadError: + # retry once + try: + if server.connect(): + return _unsafe_gat() + return None + except (_ConnectionDeadError, socket.error) as msg: + server.mark_dead(msg) + return None + def get(self, key): '''Retrieves a key from the memcache. @@ -1127,6 +1182,20 @@ def gets(self, key): ''' return self._get('gets', key) + def gat(self, key, time=1): + '''Retrieves and touches a key from the memcache. + + @return: The value or None. + ''' + return self._gat('gat', key, time=time) + + def gats(self, key, time=1): + '''Retrieves and touches a key from the memcache. Used in conjunction with 'cas'. + + @return: The value or None. + ''' + return self._gat('gats', key, time=time) + def get_multi(self, keys, key_prefix=''): '''Retrieves multiple keys from the memcache doing just one query. @@ -1440,7 +1509,8 @@ def readline(self, raise_exception=False): if self.socket: recv = self.socket.recv else: - recv = lambda bufsize: b'' + def recv(bufsize): + return b'' while True: index = buf.find(b'\r\n') diff --git a/tests/test_memcache.py b/tests/test_memcache.py index 40b6524..58f28a0 100644 --- a/tests/test_memcache.py +++ b/tests/test_memcache.py @@ -45,6 +45,17 @@ def test_setget(self): self.check_setget("an_integer", 42) self.check_setget("an_integer_2", 42, noreply=True) + def check_setgat(self, key, val, noreply=False): + self.mc.set(key, val, 20, noreply=noreply) + newval = self.mc.gat(key, 2) + self.assertEqual(newval, val) + + def test_setgat(self): + self.check_setgat("gat_a_string", "some random string") + self.check_setgat("gat_a_string_2", "some random string", noreply=True) + self.check_setgat("gat_an_integer", 42) + self.check_setgat("gat_an_integer_2", 42, noreply=True) + def test_delete(self): self.check_setget("long", int(1 << 30)) result = self.mc.delete("long") From c14c7ce51795e67c82b8a00903b56fb2d1ba4c3d Mon Sep 17 00:00:00 2001 From: svanellewee Date: Thu, 8 Nov 2018 08:19:28 +0200 Subject: [PATCH 2/2] flake8 mods --- setup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 93cbe4d..4be2b19 100644 --- a/setup.py +++ b/setup.py @@ -4,6 +4,9 @@ from setuptools import setup # noqa +dl_url = "https://github.com/linsomniac/python-memcached/releases/download/{0}/python-memcached-{0}.tar.gz" # noqa + + version = get_module_constant('memcache', '__version__') setup( name="python-memcached", @@ -15,7 +18,7 @@ maintainer="Sean Reifschneider", maintainer_email="jafo@tummy.com", url="https://github.com/linsomniac/python-memcached", - download_url="https://github.com/linsomniac/python-memcached/releases/download/{0}/python-memcached-{0}.tar.gz".format(version), + download_url=dl_url.format(version), py_modules=["memcache"], install_requires=open('requirements.txt').read().split(), classifiers=[