Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

managers.py 2.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from __future__ import absolute_import
  2. from functools import wraps
  3. from django.db import transaction, connection, models
  4. try:
  5. from django.db import connections, router
  6. except ImportError: # pre-Django 1.2
  7. connections = router = None # noqa
  8. try:
  9. transaction.atomic
  10. except AttributeError:
  11. commit_on_success = transaction.commit_on_success
  12. else:
  13. def commit_on_success(fun):
  14. @wraps(fun)
  15. def _commit(*args, **kwargs):
  16. with transaction.atomic():
  17. return fun(*args, **kwargs)
  18. return _commit
  19. class QueueManager(models.Manager):
  20. def publish(self, queue_name, payload):
  21. queue, created = self.get_or_create(name=queue_name)
  22. queue.messages.create(payload=payload)
  23. def fetch(self, queue_name):
  24. try:
  25. queue = self.get(name=queue_name)
  26. except self.model.DoesNotExist:
  27. return
  28. return queue.messages.pop()
  29. def size(self, queue_name):
  30. return self.get(name=queue_name).messages.count()
  31. def purge(self, queue_name):
  32. try:
  33. queue = self.get(name=queue_name)
  34. except self.model.DoesNotExist:
  35. return
  36. messages = queue.messages.all()
  37. count = messages.count()
  38. messages.delete()
  39. return count
  40. def select_for_update(qs):
  41. if connection.vendor == 'oracle':
  42. return qs
  43. try:
  44. return qs.select_for_update()
  45. except AttributeError:
  46. return qs
  47. class MessageManager(models.Manager):
  48. _messages_received = [0]
  49. cleanup_every = 10
  50. @commit_on_success
  51. def pop(self):
  52. try:
  53. resultset = select_for_update(
  54. self.filter(visible=True).order_by('sent_at', 'id')
  55. )
  56. result = resultset[0:1].get()
  57. result.visible = False
  58. result.save()
  59. recv = self.__class__._messages_received
  60. recv[0] += 1
  61. if not recv[0] % self.cleanup_every:
  62. self.cleanup()
  63. return result.payload
  64. except self.model.DoesNotExist:
  65. pass
  66. def cleanup(self):
  67. cursor = self.connection_for_write().cursor()
  68. cursor.execute(
  69. 'DELETE FROM %s WHERE visible=%%s' % (
  70. self.model._meta.db_table, ),
  71. (False, )
  72. )
  73. def connection_for_write(self):
  74. if connections:
  75. return connections[router.db_for_write(self.model)]
  76. return connection