Getting task_id inside a Celery task

后端 未结 3 351
夕颜
夕颜 2021-01-04 05:48

This is probably a stupid question but its got me stumped coming from a Ruby background.

I have an object that looks like this when I try to print it.



        
相关标签:
3条回答
  • 2021-01-04 06:22

    In order to make your tasks more "OO-like", you could use the bind argument to get a reference to self:

    @celery.task(bind=True)
    def scan(self, host):
      print self.request.id
    

    Please note that self.request.id is actually an instance of AsyncTask. In order to have the task id as a string, you should do self.request.id.__str__().

    From Celery's documentation (after the example):

    The bind argument means that the function will be a “bound method” so that you can access attributes and methods on the task type instance.

    0 讨论(0)
  • 2021-01-04 06:24

    Short story, within function scan, use scan.request.id.

    See http://docs.celeryproject.org/en/latest/userguide/tasks.html?highlight=request#task-request-info

    0 讨论(0)
  • 2021-01-04 06:24

    You are accessing the property from the class, while task_id is a property of instances of AsyncResult.

    To obtain the value of task_id you first have to create an instance of that class, afterwards accessing async_result_instance.task_id will return you the real id.

    In your updated code:

    @celery.task
    def scan(host):
        print celery.AsyncResult.task_id
        # ...
    

    Here you are accessing the class as I've already explained. What you want is an instance of the currently executing task. You might use celery.current_task to get the currently executing task-object:

    @celery.task
    def scan(host):
        print celery.current_task.task_id
    

    Or, if you are interested in the unique id use the request attribute of the decorated function:

    @celery.task
    def scan(host):
        print scan.request.id
        cmd = 'ps -ef'
        cm = shlex.split(cmd)
        # IMPORTANT: Do *not* use "scan = ..."!
        result = subprocess.check_output(cm)
        return result
    

    In this second case do not use any local variable called scan otherwise you'll an UnboundLocalError.

    (Code not tested since I don't have celery installed.)


    The propertys are descriptors used to provide attribute-like access to getter/setter methods, so that you can access data like:

    instance.attribute
    instance.attribute = value
    

    But when the code is executed the setter or getter can control what's going on.

    You can verify this with a dummy class:

    >>> class Dummy(object):
    ...     @property
    ...     def a(self):
    ...             print("called the getter!")
    ...             return 1
    ... 
    >>> Dummy.a
    <property object at 0x7fdae86978e8>
    >>> Dummy().a
    called the getter!
    1
    
    0 讨论(0)
提交回复
热议问题