memcache クライアントを実装してみた その2
目的
- 前回 methaneさんにコメントで指摘された部分の修正
ソース
- 修正した関数は以下の2つなので今回はその部分のソースのみ載せます
- set
- get
21 def set(self, key, value, exptime=0, flags=0): 22 # translate value to binary 23 pickled_value = pickle.dumps(value, 2) 24 length = len(pickled_value) 25 totalsent = 0 26 27 # request 28 sendmsg = "set %s %d %s %d" % (key, flags, exptime, length) 29 sendmsg += "\r\n" 30 sendmsg += pickled_value 31 sendmsg += "\r\n" 32 33 while totalsent < length: 34 sent = self.__sock.send(sendmsg[totalsent:]) 35 totalsent += sent 36 37 # response 38 recvmsg = '' 39 40 while True: 41 chunk = self.__sock.recv(BUFSIZE) 42 recvmsg += chunk 43 44 if recvmsg.find("\r\n") != -1: 45 break 46 47 # return 48 if recvmsg == "STORED\r\n": 49 return True 50 else: 51 return False 52 53 54 def get(self, key): 55 # request 56 sendmsg = "get %s\r\n" % key 57 length = len(sendmsg) 58 totalsent = 0 59 60 while totalsent < length: 61 sent = self.__sock.send(sendmsg[totalsent:]) 62 totalsent += sent 63 64 # response 65 recvmsg = '' 66 67 ## header 68 header = '' 69 70 while True: 71 chunk = self.__sock.recv(BUFSIZE) 72 recvmsg += chunk 73 74 if header == '' and recvmsg.find("\r\n") != -1: 75 [header, dummy] = recvmsg.split("\r\n", 1) 76 break 77 78 [dummy1, dummy2, dummy3, length] = header.split() 79 80 ## body 81 body = '' 82 length = len(header) + len("\r\n") + int(length) + len("\r\n") + len("END\r\n") 83 84 totalrecv = len(recvmsg) 85 86 while totalrecv < length: 87 chunk = self.__sock.recv(BUFSIZE) 88 recvmsg += chunk 89 totalrecv += len(chunk) 90 91 [header, body] = recvmsg.split("\r\n", 1) 92 [pickled_value, dummy1, dummy2] = body.rsplit("\r\n", 2) 93 94 # return 95 return pickle.loads(pickled_value)
修正点
- set
- value をバイナリに変換
- メッセージを確実に全て送信
- メッセージを少なくとも必要な分は全て受信
- get
結果
- BUFSIZE = 2 (recv が一度に受信する最大バイト数) として実行したが、前回と同様の結果が得られた