Skip to content

Commit 52a4477

Browse files
committed
gat implementation & flake8 update
1 parent bad4122 commit 52a4477

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

memcache.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,61 @@ def _unsafe_get():
11131113
server.mark_dead(msg)
11141114
return None
11151115

1116+
def _gat(self, cmd, key, time, noreply=False):
1117+
key = self._encode_key(key)
1118+
if self.do_check_key:
1119+
self.check_key(key)
1120+
server, key = self._get_server(key)
1121+
if not server:
1122+
return None
1123+
1124+
def _unsafe_gat():
1125+
self._statlog(cmd)
1126+
try:
1127+
_time = str(time)
1128+
_time = _time.encode('utf-8')
1129+
cmd_bytes = cmd.encode('utf-8') if six.PY3 else cmd
1130+
fullcmd = b''.join((cmd_bytes, b' ', _time, b' ', key))
1131+
server.send_cmd(fullcmd)
1132+
rkey = flags = rlen = cas_id = None
1133+
1134+
if cmd == 'gats':
1135+
rkey, flags, rlen, cas_id, = self._expect_cas_value(
1136+
server, raise_exception=True
1137+
)
1138+
if rkey and self.cache_cas:
1139+
self.cas_ids[rkey] = cas_id
1140+
else:
1141+
rkey, flags, rlen, = self._expectvalue(
1142+
server, raise_exception=True
1143+
)
1144+
1145+
if not rkey:
1146+
return None
1147+
try:
1148+
value = self._recv_value(server, flags, rlen)
1149+
finally:
1150+
server.expect(b"END", raise_exception=True)
1151+
except (_Error, socket.error) as msg:
1152+
if isinstance(msg, tuple):
1153+
msg = msg[1]
1154+
server.mark_dead(msg)
1155+
return None
1156+
1157+
return value
1158+
1159+
try:
1160+
return _unsafe_gat()
1161+
except _ConnectionDeadError:
1162+
# retry once
1163+
try:
1164+
if server.connect():
1165+
return _unsafe_gat()
1166+
return None
1167+
except (_ConnectionDeadError, socket.error) as msg:
1168+
server.mark_dead(msg)
1169+
return None
1170+
11161171
def get(self, key):
11171172
'''Retrieves a key from the memcache.
11181173
@@ -1127,6 +1182,20 @@ def gets(self, key):
11271182
'''
11281183
return self._get('gets', key)
11291184

1185+
def gat(self, key, time=1):
1186+
'''Retrieves and touches a key from the memcache.
1187+
1188+
@return: The value or None.
1189+
'''
1190+
return self._gat('gat', key, time=time)
1191+
1192+
def gats(self, key, time=1):
1193+
'''Retrieves and touches a key from the memcache. Used in conjunction with 'cas'.
1194+
1195+
@return: The value or None.
1196+
'''
1197+
return self._gat('gats', key, time=time)
1198+
11301199
def get_multi(self, keys, key_prefix=''):
11311200
'''Retrieves multiple keys from the memcache doing just one query.
11321201
@@ -1440,7 +1509,8 @@ def readline(self, raise_exception=False):
14401509
if self.socket:
14411510
recv = self.socket.recv
14421511
else:
1443-
recv = lambda bufsize: b''
1512+
def recv(bufsize):
1513+
return b''
14441514

14451515
while True:
14461516
index = buf.find(b'\r\n')

tests/test_memcache.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ def test_setget(self):
4545
self.check_setget("an_integer", 42)
4646
self.check_setget("an_integer_2", 42, noreply=True)
4747

48+
def check_setgat(self, key, val, noreply=False):
49+
self.mc.set(key, val, 20, noreply=noreply)
50+
newval = self.mc.gat(key, 2)
51+
self.assertEqual(newval, val)
52+
53+
def test_setgat(self):
54+
self.check_setgat("gat_a_string", "some random string")
55+
self.check_setgat("gat_a_string_2", "some random string", noreply=True)
56+
self.check_setgat("gat_an_integer", 42)
57+
self.check_setgat("gat_an_integer_2", 42, noreply=True)
58+
4859
def test_delete(self):
4960
self.check_setget("long", int(1 << 30))
5061
result = self.mc.delete("long")

0 commit comments

Comments
 (0)