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.

snapshot.py 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.events.snapshot
  4. ~~~~~~~~~~~~~~~~~~~~~~
  5. Consuming the events as a stream is not always suitable
  6. so this module implements a system to take snapshots of the
  7. state of a cluster at regular intervals. There is a full
  8. implementation of this writing the snapshots to a database
  9. in :mod:`djcelery.snapshots` in the `django-celery` distribution.
  10. """
  11. from __future__ import absolute_import
  12. from kombu.utils.limits import TokenBucket
  13. from celery import platforms
  14. from celery.app import app_or_default
  15. from celery.utils.timer2 import Timer
  16. from celery.utils.dispatch import Signal
  17. from celery.utils.imports import instantiate
  18. from celery.utils.log import get_logger
  19. from celery.utils.timeutils import rate
  20. __all__ = ['Polaroid', 'evcam']
  21. logger = get_logger('celery.evcam')
  22. class Polaroid(object):
  23. timer = None
  24. shutter_signal = Signal(providing_args=('state', ))
  25. cleanup_signal = Signal()
  26. clear_after = False
  27. _tref = None
  28. _ctref = None
  29. def __init__(self, state, freq=1.0, maxrate=None,
  30. cleanup_freq=3600.0, timer=None, app=None):
  31. self.app = app_or_default(app)
  32. self.state = state
  33. self.freq = freq
  34. self.cleanup_freq = cleanup_freq
  35. self.timer = timer or self.timer or Timer()
  36. self.logger = logger
  37. self.maxrate = maxrate and TokenBucket(rate(maxrate))
  38. def install(self):
  39. self._tref = self.timer.call_repeatedly(self.freq, self.capture)
  40. self._ctref = self.timer.call_repeatedly(
  41. self.cleanup_freq, self.cleanup,
  42. )
  43. def on_shutter(self, state):
  44. pass
  45. def on_cleanup(self):
  46. pass
  47. def cleanup(self):
  48. logger.debug('Cleanup: Running...')
  49. self.cleanup_signal.send(None)
  50. self.on_cleanup()
  51. def shutter(self):
  52. if self.maxrate is None or self.maxrate.can_consume():
  53. logger.debug('Shutter: %s', self.state)
  54. self.shutter_signal.send(self.state)
  55. self.on_shutter(self.state)
  56. def capture(self):
  57. self.state.freeze_while(self.shutter, clear_after=self.clear_after)
  58. def cancel(self):
  59. if self._tref:
  60. self._tref() # flush all received events.
  61. self._tref.cancel()
  62. if self._ctref:
  63. self._ctref.cancel()
  64. def __enter__(self):
  65. self.install()
  66. return self
  67. def __exit__(self, *exc_info):
  68. self.cancel()
  69. def evcam(camera, freq=1.0, maxrate=None, loglevel=0,
  70. logfile=None, pidfile=None, timer=None, app=None):
  71. app = app_or_default(app)
  72. if pidfile:
  73. platforms.create_pidlock(pidfile)
  74. app.log.setup_logging_subsystem(loglevel, logfile)
  75. print('-> evcam: Taking snapshots with {0} (every {1} secs.)'.format(
  76. camera, freq))
  77. state = app.events.State()
  78. cam = instantiate(camera, state, app=app, freq=freq,
  79. maxrate=maxrate, timer=timer)
  80. cam.install()
  81. conn = app.connection()
  82. recv = app.events.Receiver(conn, handlers={'*': state.event})
  83. try:
  84. try:
  85. recv.capture(limit=None)
  86. except KeyboardInterrupt:
  87. raise SystemExit
  88. finally:
  89. cam.cancel()
  90. conn.close()