cachebuster.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from django.db.models import F
  2. from . import threadstore
  3. CACHE_KEY = 'misago_cachebuster'
  4. class CacheBusterController(object):
  5. def register_cache(self, cache):
  6. from .models import CacheVersion
  7. CacheVersion.objects.create(cache=cache)
  8. def unregister_cache(self, cache):
  9. from .models import CacheVersion
  10. try:
  11. cache = CacheVersion.objects.get(cache=cache)
  12. cache.delete()
  13. except CacheVersion.DoesNotExist:
  14. raise ValueError('Cache "%s" is not registered' % cache)
  15. @property
  16. def cache(self):
  17. return self.read_threadstore()
  18. def read_threadstore(self):
  19. data = threadstore.get(CACHE_KEY, 'nada')
  20. if data == 'nada':
  21. data = self.read_cache()
  22. threadstore.set(CACHE_KEY, data)
  23. return data
  24. def read_cache(self):
  25. from .cache import cache as default_cache
  26. data = default_cache.get(CACHE_KEY, 'nada')
  27. if data == 'nada':
  28. data = self.read_db()
  29. default_cache.set(CACHE_KEY, data)
  30. return data
  31. def read_db(self):
  32. from .models import CacheVersion
  33. data = {}
  34. for cache_version in CacheVersion.objects.iterator():
  35. data[cache_version.cache] = cache_version.version
  36. return data
  37. def get_cache_version(self, cache):
  38. try:
  39. return self.cache[cache]
  40. except KeyError:
  41. raise ValueError('Cache "%s" is not registered' % cache)
  42. def is_cache_valid(self, cache, version):
  43. try:
  44. return self.cache[cache] == version
  45. except KeyError:
  46. raise ValueError('Cache "%s" is not registered' % cache)
  47. def invalidate_cache(self, cache):
  48. from .cache import cache as default_cache
  49. from .models import CacheVersion
  50. self.cache[cache] += 1
  51. CacheVersion.objects.filter(cache=cache).update(
  52. version=F('version') + 1)
  53. default_cache.delete(CACHE_KEY)
  54. def invalidate_all(self):
  55. from .cache import cache as default_cache
  56. from .models import CacheVersion
  57. CacheVersion.objects.update(version=F('version') + 1)
  58. default_cache.delete(CACHE_KEY)
  59. _controller = CacheBusterController()
  60. # Expose controller API
  61. def register(cache):
  62. _controller.register_cache(cache)
  63. def unregister(cache):
  64. _controller.unregister_cache(cache)
  65. def get_version(cache):
  66. return _controller.get_cache_version(cache)
  67. def is_valid(cache, version):
  68. return _controller.is_cache_valid(cache, version)
  69. def invalidate(cache):
  70. _controller.invalidate_cache(cache)
  71. def invalidate_all():
  72. _controller.invalidate_all()