ソースを参照

Merge branch 'malinoff/custom-gen_task_name'

Ask Solem 11 年 前
コミット
b6bec5ea36
4 ファイル変更55 行追加5 行削除
  1. 1 2
      celery/app/__init__.py
  2. 4 1
      celery/app/base.py
  3. 1 2
      celery/task/base.py
  4. 49 0
      docs/userguide/tasks.rst

+ 1 - 2
celery/app/__init__.py

@@ -17,7 +17,6 @@ from celery._state import (
     get_current_task as current_task,
     connect_on_app_finalize, set_default_app, _get_active_apps, _task_stack,
 )
-from celery.utils import gen_task_name
 
 from .base import Celery, AppPickler
 
@@ -140,7 +139,7 @@ def shared_task(*args, **kwargs):
             def task_by_cons():
                 app = current_app()
                 return app.tasks[
-                    name or gen_task_name(app, fun.__name__, fun.__module__)
+                    name or app.gen_task_name(fun.__name__, fun.__module__)
                 ]
             return Proxy(task_by_cons)
         return __inner

+ 4 - 1
celery/app/base.py

@@ -268,7 +268,7 @@ class Celery(object):
     def _task_from_fun(self, fun, name=None, base=None, bind=False, **options):
         if not self.finalized and not self.autofinalize:
             raise RuntimeError('Contract breach: app not finalized')
-        name = name or gen_task_name(self, fun.__name__, fun.__module__)
+        name = name or self.gen_task_name(fun.__name__, fun.__module__)
         base = base or self.Task
 
         if name not in self._tasks:
@@ -286,6 +286,9 @@ class Celery(object):
             task = self._tasks[name]
         return task
 
+    def gen_task_name(self, name, module):
+        return gen_task_name(self, name, module)
+
     def finalize(self, auto=False):
         with self._finalize_mutex:
             if not self.finalized:

+ 1 - 2
celery/task/base.py

@@ -18,7 +18,6 @@ from celery.app.task import Context, Task as BaseTask, _reprtask
 from celery.five import class_property, reclassmethod, with_metaclass
 from celery.local import Proxy
 from celery.schedules import maybe_schedule
-from celery.utils import gen_task_name
 from celery.utils.log import get_task_logger
 
 __all__ = ['Context', 'Task', 'TaskType', 'PeriodicTask', 'task']
@@ -86,7 +85,7 @@ class TaskType(type):
         # - Automatically generate missing/empty name.
         task_name = attrs.get('name')
         if not task_name:
-            attrs['name'] = task_name = gen_task_name(app, name, task_module)
+            attrs['name'] = task_name = app.gen_task_name(name, task_module)
 
         if not attrs.get('_decorated'):
             # non decorated tasks must also be shared in case

+ 49 - 0
docs/userguide/tasks.rst

@@ -215,6 +215,55 @@ on the automatic naming:
     def add(x, y):
         return x + y
 
+.. _task-name-generator-info:
+
+Changing the automatic naming behavior
+--------------------------------------
+
+.. versionadded:: 3.2
+
+There are some cases when the default automatic naming is not suitable.
+Consider you have many tasks within many different modules::
+
+    project/
+           /__init__.py
+           /celery.py
+           /moduleA/
+                   /__init__.py
+                   /tasks.py
+           /moduleB/
+                   /__init__.py
+                   /tasks.py
+
+Using the default automatic naming, each task will have a generated name
+like `moduleA.tasks.taskA`, `moduleA.tasks.taskB`, `moduleB.tasks.test`
+and so on. You may want to get rid of having `tasks` in all task names.
+As pointed above, you can explicitly give names for all tasks, or you
+can change the automatic naming behavior by overriding
+:meth:`~@Celery.gen_task_name`. Continuing with the example, `celery.py`
+may contain:
+
+.. code-block:: python
+
+    from celery import Celery
+
+    class MyCelery(Celery):
+
+        def gen_task_name(self, name, module):
+            if module.endswith('.tasks'):
+                module = module[:-6]
+            return super(MyCelery, self).gen_task_name(name, module)
+
+    app = MyCelery('main')
+
+So each task will have a name like `moduleA.taskA`, `moduleA.taskB` and
+`moduleB.test`.
+
+.. warning::
+
+    Make sure that your `gen_task_name` is a pure function, which means
+    that for the same input it must always return the same output.
+
 .. _task-request-info:
 
 Context