monitor.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from datetime import timedelta
  2. from django.core.cache import cache
  3. from django.utils import timezone
  4. from misago.thread import local
  5. _thread_local = local()
  6. def load_monitor():
  7. from misago.models import MonitorItem
  8. monitor = cache.get('monitor', {})
  9. if not monitor:
  10. for i in MonitorItem.objects.all():
  11. monitor[i.id] = [i.value, i.updated, i.type]
  12. cache.set('monitor', monitor)
  13. return monitor
  14. def refresh_monitor():
  15. _thread_local.monitor = load_monitor()
  16. class Monitor(object):
  17. def __init__(self, local):
  18. self.thread = local
  19. def monitor(self):
  20. try:
  21. return self.thread.monitor
  22. except AttributeError:
  23. self.thread.monitor = load_monitor()
  24. return self.thread.monitor
  25. def entry(self, key):
  26. try:
  27. return self.monitor()[key]
  28. except KeyError:
  29. raise Exception(u"Monitor entry \"%s\" could not be found." % key)
  30. def __contains__(self, key):
  31. return key in self.monitor()
  32. def __getattr__(self, key):
  33. return self.entry(key)[0]
  34. def __getitem__(self, key):
  35. return self.entry(key)[0]
  36. def __setitem__(self, key, value):
  37. self.thread.monitor_update.append((key, value))
  38. return value
  39. def increase(self, key, i=1):
  40. self.thread.monitor_update.append((key, self[key] + i))
  41. def decrease(self, key, i=1):
  42. self.thread.monitor_update.append((key, self[key] - i))
  43. def get(self, key, default=None):
  44. if not key in self.monitor():
  45. return default
  46. return self.entry(key)[0]
  47. def get_updated(self, key):
  48. if key in self.monitor():
  49. return self.entry(key)[1]
  50. return None
  51. def expired(self, key, seconds=5):
  52. return self.entry(key)[1] < (timezone.now() - timedelta(seconds=seconds))
  53. def has_key(self, key):
  54. return key in self.entry()
  55. def keys(self):
  56. return self.entry().keys()
  57. def values(self):
  58. return self.entry().values()
  59. def items(self):
  60. return self.entry().items()
  61. def iterkeys(self):
  62. return self.entry().iterkeys()
  63. def itervalues(self):
  64. return self.entry().itervalues()
  65. def iteritems(self):
  66. return self.entry().iteritems()
  67. class UpdatingMonitor(object):
  68. def __enter__(self):
  69. _thread_local.monitor_update = []
  70. def __exit__(self, type, value, traceback):
  71. if _thread_local.monitor_update:
  72. from misago.models import MonitorItem
  73. for key, value in _thread_local.monitor_update:
  74. MonitorItem.objects.filter(pk=key).update(_value=value, updated=timezone.now())
  75. cache.delete('monitor')
  76. _thread_local.monitor_update = None
  77. monitor = Monitor(_thread_local)