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.

__init__.py 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.app
  4. ~~~~~~~~~~
  5. Celery Application.
  6. """
  7. from __future__ import absolute_import
  8. import os
  9. from celery.local import Proxy
  10. from celery import _state
  11. from celery._state import (
  12. get_current_app as current_app,
  13. get_current_task as current_task,
  14. connect_on_app_finalize, set_default_app, _get_active_apps, _task_stack,
  15. )
  16. from celery.utils import gen_task_name
  17. from .base import Celery, AppPickler
  18. __all__ = ['Celery', 'AppPickler', 'default_app', 'app_or_default',
  19. 'bugreport', 'enable_trace', 'disable_trace', 'shared_task',
  20. 'set_default_app', 'current_app', 'current_task',
  21. 'push_current_task', 'pop_current_task']
  22. #: Proxy always returning the app set as default.
  23. default_app = Proxy(lambda: _state.default_app)
  24. #: Function returning the app provided or the default app if none.
  25. #:
  26. #: The environment variable :envvar:`CELERY_TRACE_APP` is used to
  27. #: trace app leaks. When enabled an exception is raised if there
  28. #: is no active app.
  29. app_or_default = None
  30. #: The 'default' loader is the default loader used by old applications.
  31. #: This is deprecated and should no longer be used as it's set too early
  32. #: to be affected by --loader argument.
  33. default_loader = os.environ.get('CELERY_LOADER') or 'default' # XXX
  34. #: Function used to push a task to the thread local stack
  35. #: keeping track of the currently executing task.
  36. #: You must remember to pop the task after.
  37. push_current_task = _task_stack.push
  38. #: Function used to pop a task from the thread local stack
  39. #: keeping track of the currently executing task.
  40. pop_current_task = _task_stack.pop
  41. def bugreport(app=None):
  42. return (app or current_app()).bugreport()
  43. def _app_or_default(app=None):
  44. if app is None:
  45. return _state.get_current_app()
  46. return app
  47. def _app_or_default_trace(app=None): # pragma: no cover
  48. from traceback import print_stack
  49. from billiard import current_process
  50. if app is None:
  51. if getattr(_state._tls, 'current_app', None):
  52. print('-- RETURNING TO CURRENT APP --') # noqa+
  53. print_stack()
  54. return _state._tls.current_app
  55. if current_process()._name == 'MainProcess':
  56. raise Exception('DEFAULT APP')
  57. print('-- RETURNING TO DEFAULT APP --') # noqa+
  58. print_stack()
  59. return _state.default_app
  60. return app
  61. def enable_trace():
  62. global app_or_default
  63. app_or_default = _app_or_default_trace
  64. def disable_trace():
  65. global app_or_default
  66. app_or_default = _app_or_default
  67. if os.environ.get('CELERY_TRACE_APP'): # pragma: no cover
  68. enable_trace()
  69. else:
  70. disable_trace()
  71. App = Celery # XXX Compat
  72. def shared_task(*args, **kwargs):
  73. """Create shared tasks (decorator).
  74. Will return a proxy that always takes the task from the current apps
  75. task registry.
  76. This can be used by library authors to create tasks that will work
  77. for any app environment.
  78. Example:
  79. >>> from celery import Celery, shared_task
  80. >>> @shared_task
  81. ... def add(x, y):
  82. ... return x + y
  83. >>> app1 = Celery(broker='amqp://')
  84. >>> add.app is app1
  85. True
  86. >>> app2 = Celery(broker='redis://')
  87. >>> add.app is app2
  88. """
  89. def create_shared_task(**options):
  90. def __inner(fun):
  91. name = options.get('name')
  92. # Set as shared task so that unfinalized apps,
  93. # and future apps will load the task.
  94. connect_on_app_finalize(
  95. lambda app: app._task_from_fun(fun, **options)
  96. )
  97. # Force all finalized apps to take this task as well.
  98. for app in _get_active_apps():
  99. if app.finalized:
  100. with app._finalize_mutex:
  101. app._task_from_fun(fun, **options)
  102. # Return a proxy that always gets the task from the current
  103. # apps task registry.
  104. def task_by_cons():
  105. app = current_app()
  106. return app.tasks[
  107. name or gen_task_name(app, fun.__name__, fun.__module__)
  108. ]
  109. return Proxy(task_by_cons)
  110. return __inner
  111. if len(args) == 1 and callable(args[0]):
  112. return create_shared_task(**kwargs)(args[0])
  113. return create_shared_task(*args, **kwargs)