How to recursively chain a Celery task that returns a list into a group?

后端 未结 1 482
抹茶落季
抹茶落季 2021-01-13 14:48

I started from this question: How to chain a Celery task that returns a list into a group?

But I want to expand twice. So in my use case I have:

  • task
相关标签:
1条回答
  • 2021-01-13 15:05

    Turns out the problem is that the clone() method on a chain instance does not pass the arguments through at some point - see https://stackoverflow.com/a/53442344/3189 for the full details. If I use the method in that answer, my dmap() code becomes:

    @app.task
    def dmap(args_iter, celery_task):
        """
        Takes an iterator of argument tuples and queues them up for celery to run with the function.
        """
        callback = subtask(celery_task)
        run_in_parallel = group(clone_signature(callback, args) for args in args_iter)
        return run_in_parallel.delay()
    
    
    def clone_signature(sig, args=(), kwargs=(), **opts):
        """
        Turns out that a chain clone() does not copy the arguments properly - this
        clone does.
        From: https://stackoverflow.com/a/53442344/3189
        """
        if sig.subtask_type and sig.subtask_type != "chain":
            raise NotImplementedError(
                "Cloning only supported for Tasks and chains, not {}".format(sig.subtask_type)
            )
        clone = sig.clone()
        if hasattr(clone, "tasks"):
            task_to_apply_args_to = clone.tasks[0]
        else:
            task_to_apply_args_to = clone
        args, kwargs, opts = task_to_apply_args_to._merge(args=args, kwargs=kwargs, options=opts)
        task_to_apply_args_to.update(args=args, kwargs=kwargs, options=deepcopy(opts))
        return clone
    

    And then when I do:

    ppp = (task_range.s() | dmap.s(add.s() | dmap.s(combine_log.s())))
    

    everything works as expected.

    0 讨论(0)
提交回复
热议问题