Advertisement
Guest User

Untitled

a guest
May 29th, 2016
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.60 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. from threading import Thread
  4. from tornado import gen, ioloop
  5. from tornado.queues import Queue as AsyncQueue
  6. import random, json, time, logging, Queue
  7. import shelve
  8.  
  9. _db = None
  10. _cmd_q = None # command queue (consumed by db loop)
  11. _val_q = None # values queue (consumed by io loop)
  12. _thread = None
  13.  
  14. def _db_loop():
  15. global _db, _cmd_q, _val_q
  16. io_loop = ioloop.IOLoop.instance()
  17. quit = False
  18. while not quit:
  19. q_cmd = None
  20. try:
  21. q_cmd = _cmd_q.get(True)
  22. except Queue.Empty:
  23. continue
  24. #
  25. if q_cmd is None or not 'cmd' in q_cmd:
  26. pass
  27. elif q_cmd['cmd'] == 'get':
  28. k = q_cmd['key']
  29. if not _db.has_key(k):
  30. v = None
  31. else:
  32. v = _db[k]
  33. io_loop.add_callback(_return_val, v) # queue response to the io loop
  34. elif q_cmd['cmd'] == 'set':
  35. k, v = q_cmd['key'], q_cmd['value']
  36. _db[k] = v
  37. _db.sync() # playing it safe here
  38. elif q_cmd['cmd'] == 'quit':
  39. quit = True
  40. # end of task
  41. _cmd_q.task_done()
  42. # end of loop
  43. _db.close()
  44.  
  45. def _return_val(value):
  46. global _val_q
  47. _val_q.put(value)
  48.  
  49. ## -- Module interface (to use from the IO loop) --
  50. __all__ = [ "init", "get", "set", "quit" ]
  51.  
  52. def init(path):
  53. global _db, _cmd_q, _val_q, _thread
  54. _db = shelve.open(path)
  55. _cmd_q = Queue.Queue() # command queue (consumed by db loop)
  56. _val_q = AsyncQueue() # values queue (consumed by io loop)
  57. # ... run db_loop in its own thread ...
  58. _thread = Thread(target=_db_loop)
  59. _thread.start()
  60.  
  61. @gen.coroutine
  62. def get(k):
  63. global _cmd_q, _val_q
  64. _cmd_q.put(dict(cmd='get', key=k), True) # Block while putting get commands to ensure consistent order
  65. value = yield _val_q.get()
  66. _val_q.task_done()
  67. raise gen.Return(value)
  68.  
  69. def set(k, v):
  70. global _cmd_q
  71. _cmd_q.put(dict(cmd='set', key=k, value=v), False)
  72.  
  73. def quit():
  74. global _cmd_q
  75. _cmd_q.put(dict(cmd='quit'))
  76.  
  77.  
  78. if __name__ == "__main__":
  79. from tornado.options import parse_command_line
  80. import signal
  81.  
  82. logger = logging.getLogger('tornado.general')
  83.  
  84. @gen.coroutine
  85. def test():
  86. logger.info("Starting test")
  87. set('a', 1)
  88. logger.info("a = %d", (yield get('a')))
  89. logger.info("b = %s", str((yield get('b'))))
  90. for x in range(1,10):
  91. set('x%d' % x, x**2)
  92. for x in range(1,10):
  93. logger.info("x%d = %d" % (x, (yield get('x%d' % x))))
  94.  
  95. def on_shutdown():
  96. quit()
  97. ioloop.IOLoop.current().stop()
  98.  
  99. parse_command_line()
  100. init('state_test')
  101. ioloop.IOLoop.current().spawn_callback(test)
  102. signal.signal(signal.SIGINT, lambda sig, frame: ioloop.IOLoop.current().add_callback_from_signal(on_shutdown))
  103. ioloop.IOLoop.current().start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement