|
@@ -201,7 +201,8 @@ class chain(Signature):
|
|
|
|
|
|
def __init__(self, *tasks, **options):
|
|
|
tasks = tasks[0] if len(tasks) == 1 and is_list(tasks[0]) else tasks
|
|
|
- Signature.__init__(self, 'celery.chain', (), {'tasks': tasks}, options)
|
|
|
+ Signature.__init__(self, 'celery.chain', (), {'tasks': tasks},
|
|
|
+ options, immutable=True)
|
|
|
self.tasks = tasks
|
|
|
self.subtask_type = 'chain'
|
|
|
|
|
@@ -223,7 +224,7 @@ class _basemap(Signature):
|
|
|
|
|
|
def __init__(self, task, it, **options):
|
|
|
Signature.__init__(self, self._task_name, (),
|
|
|
- {'task': task, 'it': regen(it)}, **options)
|
|
|
+ {'task': task, 'it': regen(it)}, immutable=True, **options)
|
|
|
|
|
|
def apply_async(self, args=(), kwargs={}, **opts):
|
|
|
# need to evaluate generators
|
|
@@ -259,22 +260,21 @@ class chunks(Signature):
|
|
|
|
|
|
def __init__(self, task, it, n, **options):
|
|
|
Signature.__init__(self, 'celery.chunks', (),
|
|
|
- {'task': task, 'it': regen(it), 'n': n}, **options)
|
|
|
+ {'task': task, 'it': regen(it), 'n': n},
|
|
|
+ immutable=True, **options)
|
|
|
|
|
|
@classmethod
|
|
|
def from_dict(self, d):
|
|
|
return chunks(*self._unpack_args(d['kwargs']), **d['options'])
|
|
|
|
|
|
def apply_async(self, args=(), kwargs={}, **opts):
|
|
|
- # need to evaluate generators
|
|
|
- task, it, n = self._unpack_args(self.kwargs)
|
|
|
- return self.type.apply_async((),
|
|
|
- {'task': task, 'it': list(it), 'n': n}, **opts)
|
|
|
+ return self.group().apply_async(args, kwargs, **opts)
|
|
|
|
|
|
def __call__(self, **options):
|
|
|
return self.group()(**options)
|
|
|
|
|
|
def group(self):
|
|
|
+ # need to evaluate generators
|
|
|
task, it, n = self._unpack_args(self.kwargs)
|
|
|
return group(xstarmap(task, part) for part in _chunks(iter(it), n))
|
|
|
|
|
@@ -284,12 +284,21 @@ class chunks(Signature):
|
|
|
Signature.register_type(chunks)
|
|
|
|
|
|
|
|
|
+def _maybe_group(tasks):
|
|
|
+ if isinstance(tasks, group):
|
|
|
+ tasks = list(tasks.tasks)
|
|
|
+ else:
|
|
|
+ tasks = regen(tasks if is_list(tasks) else tasks)
|
|
|
+ return tasks
|
|
|
+
|
|
|
+
|
|
|
class group(Signature):
|
|
|
|
|
|
def __init__(self, *tasks, **options):
|
|
|
- tasks = regen(tasks[0] if len(tasks) == 1 and is_list(tasks[0])
|
|
|
- else tasks)
|
|
|
- Signature.__init__(self, 'celery.group', (), {'tasks': tasks}, options)
|
|
|
+ if len(tasks) == 1:
|
|
|
+ tasks = _maybe_group(tasks[0])
|
|
|
+ Signature.__init__(self, 'celery.group', (),
|
|
|
+ {'tasks': tasks}, options, immutable=True)
|
|
|
self.tasks, self.subtask_type = tasks, 'group'
|
|
|
|
|
|
@classmethod
|
|
@@ -307,6 +316,9 @@ class group(Signature):
|
|
|
task.set(countdown=_next_skew())
|
|
|
return self
|
|
|
|
|
|
+ def __iter__(self):
|
|
|
+ return iter(self.tasks)
|
|
|
+
|
|
|
def __repr__(self):
|
|
|
return repr(self.tasks)
|
|
|
Signature.register_type(group)
|
|
@@ -317,8 +329,9 @@ class chord(Signature):
|
|
|
|
|
|
def __init__(self, header, body=None, **options):
|
|
|
Signature.__init__(self, 'celery.chord', (),
|
|
|
- {'header': regen(header),
|
|
|
- 'body': maybe_subtask(body)}, options)
|
|
|
+ {'header': _maybe_group(header),
|
|
|
+ 'body': maybe_subtask(body)},
|
|
|
+ options, immutable=True)
|
|
|
self.subtask_type = 'chord'
|
|
|
|
|
|
@classmethod
|
|
@@ -329,7 +342,7 @@ class chord(Signature):
|
|
|
|
|
|
def __call__(self, body=None, **options):
|
|
|
_chord = self.Chord
|
|
|
- self.kwargs['body'] = body or self.kwargs['body']
|
|
|
+ body = self.kwargs['body'] = body or self.kwargs['body']
|
|
|
if _chord.app.conf.CELERY_ALWAYS_EAGER:
|
|
|
return self.apply((), {}, **options)
|
|
|
callback_id = body.options.setdefault('task_id', uuid())
|