memcachedstorage.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. from __future__ import absolute_import, unicode_literals
  4. import logging
  5. import threading
  6. import time
  7. from library.wechatpy.session import SessionStorage
  8. from library import to_text
  9. from library.wechatpy.utils import json
  10. logger = logging.getLogger(__name__)
  11. class MemcachedStorage(SessionStorage):
  12. LOCAL_BUFFER = {}
  13. LOCAL_BUFFER_LOCK = threading.Lock()
  14. def __init__(self, mc, prefix = 'wechatpy'):
  15. for method_name in ('get', 'set', 'delete'):
  16. assert hasattr(mc, method_name)
  17. self.mc = mc
  18. self.prefix = prefix
  19. def key_name(self, key):
  20. return '{0}:{1}'.format(self.prefix, key)
  21. def get(self, key, default = None):
  22. key = self.key_name(key)
  23. mem_value = self.LOCAL_BUFFER.get(key, {})
  24. if mem_value and mem_value['expire'] > int(time.time()):
  25. logger.debug('=== WechatToken === hit memory. key = {}; expireAt = {}; value = {}'.format(
  26. key, mem_value['expire'], mem_value['value']))
  27. return mem_value['value']
  28. else:
  29. with self.LOCAL_BUFFER_LOCK:
  30. mem_value = self.LOCAL_BUFFER.get(key, {})
  31. if mem_value and mem_value['expire'] > int(time.time()):
  32. logger.debug(
  33. '=== WechatToken === hit memory(double check). key = {}; expireAt = {}; value = {}'.format(
  34. key, mem_value['expire'], mem_value['value']))
  35. return mem_value['value']
  36. else:
  37. logger.debug('=== WechatToken === miss memory. key = {}'.format(key))
  38. value = self.mc.get(key, ignore_exc = False)
  39. logger.debug("=== WechatToken === memcache: key = {}; result = {}".format(key, str(value)))
  40. if value is None:
  41. self.LOCAL_BUFFER.pop(key, None)
  42. return default
  43. else:
  44. value = json.loads(to_text(value))
  45. self.LOCAL_BUFFER[key] = value
  46. logger.debug('=== WechatToken === set memory. key = {}; value = {};'.format(key, value))
  47. return value['value']
  48. def set(self, key, value, ttl = 0):
  49. if value is None:
  50. return
  51. key = self.key_name(key)
  52. value = {
  53. 'expire': int(time.time()) + ttl,
  54. 'value': value
  55. }
  56. logger.debug("=== WechatToken === set memory: key = {}; value = {}; ttl = {}".format(key, value, ttl))
  57. with self.LOCAL_BUFFER_LOCK:
  58. self.LOCAL_BUFFER[key] = value
  59. logger.debug("=== WechatToken === set memcache: key = {}; value = {}; ttl = {}".format(key, value, ttl))
  60. self.mc.set(key, json.dumps(value), ttl)
  61. def delete(self, key):
  62. logger.debug("=== WechatToken === delete memcache: key = {};".format(key))
  63. key = self.key_name(key)
  64. self.mc.delete(key)