25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

89 lines
2.3 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals, absolute_import
  4. from celery import Celery
  5. # initiate logger
  6. from celery.utils.log import get_task_logger
  7. task_logger = get_task_logger(__name__)
  8. from datetime import timedelta
  9. import frappe
  10. import json
  11. import os
  12. SITES_PATH = os.environ.get('SITES_PATH', '.')
  13. # defaults
  14. DEFAULT_CELERY_BROKER = "redis://localhost"
  15. DEFAULT_CELERY_BACKEND = None
  16. DEFAULT_SCHEDULER_INTERVAL = 300
  17. LONGJOBS_PREFIX = "longjobs@"
  18. _app = None
  19. def get_celery():
  20. global _app
  21. if not _app:
  22. conf = frappe.get_site_config(sites_path=SITES_PATH)
  23. _app = Celery('frappe',
  24. broker=conf.celery_broker or DEFAULT_CELERY_BROKER,
  25. backend=conf.celery_result_backend or DEFAULT_CELERY_BACKEND)
  26. setup_celery(_app, conf)
  27. return _app
  28. def setup_celery(app, conf):
  29. app.autodiscover_tasks(frappe.get_all_apps(with_frappe=True, with_internal_apps=False,
  30. sites_path=SITES_PATH))
  31. app.conf.CELERY_TASK_SERIALIZER = 'json'
  32. app.conf.CELERY_ACCEPT_CONTENT = ['json']
  33. app.conf.CELERY_TIMEZONE = 'UTC'
  34. if conf.celery_queue_per_site:
  35. app.conf.CELERY_ROUTES = (SiteRouter(),)
  36. app.conf.CELERYBEAT_SCHEDULE = get_beat_schedule(conf)
  37. if conf.celery_error_emails:
  38. app.conf.CELERY_SEND_TASK_ERROR_EMAILS = True
  39. for k, v in conf.celery_error_emails.iteritems():
  40. setattr(app.conf, k, v)
  41. class SiteRouter(object):
  42. def route_for_task(self, task, args=None, kwargs=None):
  43. if hasattr(frappe.local, 'site'):
  44. if kwargs and kwargs.get("event", "").endswith("_long"):
  45. return get_queue(frappe.local.site, LONGJOBS_PREFIX)
  46. else:
  47. return get_queue(frappe.local.site)
  48. return None
  49. def get_queue(site, prefix=None):
  50. return {'queue': "{}{}".format(prefix or "", site)}
  51. def get_beat_schedule(conf):
  52. schedule = {
  53. 'scheduler': {
  54. 'task': 'frappe.tasks.enqueue_scheduler_events',
  55. 'schedule': timedelta(seconds=conf.scheduler_interval or DEFAULT_SCHEDULER_INTERVAL)
  56. },
  57. }
  58. if conf.celery_queue_per_site:
  59. schedule['sync_queues'] = {
  60. 'task': 'frappe.tasks.sync_queues',
  61. 'schedule': timedelta(seconds=conf.scheduler_interval or DEFAULT_SCHEDULER_INTERVAL)
  62. }
  63. return schedule
  64. def celery_task(*args, **kwargs):
  65. return get_celery().task(*args, **kwargs)
  66. if __name__ == '__main__':
  67. get_celery().start()