kvstore.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import sys
  4. import asyncio
  5. class KvStore(object):
  6. def __init__(self):
  7. self.store = {}
  8. def set(self, key, value):
  9. self.store[key] = value
  10. return '+OK'
  11. def get(self, key):
  12. if key in self.store.keys():
  13. return self.store[key]
  14. else:
  15. return '-ERROR'
  16. def truncate(self, key):
  17. if key in self.store.keys():
  18. del self.store[key]
  19. return '+OK'
  20. else:
  21. return '-ERROR'
  22. class KvStringParser(object):
  23. def __init__(self):
  24. self.data = []
  25. self.OP = ''
  26. self.KEY = ''
  27. self.VALUE = ''
  28. def parse(self, string):
  29. self.data = string.split(' ')
  30. self.OP = self.data[0]
  31. self.KEY = self.data[1].strip()
  32. if self.OP == 'GET':
  33. return 1, [ self.KEY ]
  34. elif self.OP == 'SET':
  35. self.VALUE = ' '.join(self.data[2:]).strip()
  36. return 2, [ self.KEY, self.VALUE ]
  37. elif self.OP == 'TRUNCATE':
  38. return 3, [self.KEY]
  39. else:
  40. return -1, []
  41. class KvHandler(object):
  42. def __init__(self, store, parser):
  43. self.store = store
  44. self.parser = parser
  45. async def handler(self, reader, writer):
  46. data = await reader.read(100)
  47. message = data.decode()
  48. op_type, query = self.parser.parse(message)
  49. print(op_type, query, self.store)
  50. if op_type == -1:
  51. data = '-ERROR'
  52. elif op_type == 3:
  53. data = self.store.truncate(query[0])
  54. elif op_type == 2:
  55. data = self.store.set(query[0], query[1])
  56. elif op_type == 1:
  57. data = self.store.get(query[0])
  58. else:
  59. data = '-GENERIC ERROR'
  60. addr = writer.get_extra_info('peername')
  61. print(f"Recieved {message!r} from {addr!r}")
  62. print(f"Send: {message!r}")
  63. writer.write(data.encode())
  64. await writer.drain()
  65. print("Close the connection")
  66. writer.close()
  67. async def main(port):
  68. store = KvStore()
  69. parser = KvStringParser()
  70. handler = KvHandler(store, parser)
  71. server = await asyncio.start_server(
  72. lambda r, w: handler.handler(r, w), '127.0.0.1', port)
  73. addr = server.sockets[0].getsockname()
  74. print(f'Serving on {addr}')
  75. async with server:
  76. await server.serve_forever()
  77. if len(sys.argv) == 2:
  78. asyncio.run(main(sys.argv[1]))
  79. else:
  80. print(f"Usage : python {sys.argv[0]} <PORT_NUMBER>")