Celery Task Chain and Accessing **kwargs

后端 未结 3 1056
夕颜
夕颜 2020-12-29 11:38

I have a situation similar to the one outlined here, except that instead of chaining tasks with multiple arguments, I want to chain tasks that return a dictionary with multi

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-29 12:07

    Since this isn't built into celery, I wrote a decorator function to something similar myself.

    # Use this wrapper with functions in chains that return a tuple. The
    # next function in the chain will get called with that the contents of
    # tuple as (first) positional args, rather than just as just the first
    # arg. Note that both the sending and receiving function must have
    # this wrapper, which goes between the @task decorator and the
    # function definition. This wrapper should not otherwise interfere
    # when these conditions are not met.
    
    class UnwrapMe(object):
        def __init__(self, contents):
            self.contents = contents
    
        def __call__(self):
            return self.contents
    
    def wrap_for_chain(f):
        """ Too much deep magic. """
        @functools.wraps(f)
        def _wrapper(*args, **kwargs):
            if type(args[0]) == UnwrapMe:
                args = list(args[0]()) + list(args[1:])
            result = f(*args, **kwargs)
    
            if type(result) == tuple and current_task.request.callbacks:
                return UnwrapMe(result)
            else:
                return result
        return _wrapper
    

    Mine unwraps like the starchain concept, but you could easily modify it to unwrap kwargs instead.

提交回复
热议问题