如何获取运行任务的队列 - 芹菜

时间:2014-03-13 16:42:58

标签: python queue task celery

我是新来的芹菜并有一个问题。我有这个简单的任务:

@app.task(name='test_install_queue')
def test_install_queue():
    return subprocess.call("exit 0",shell=True)

我稍后在像

这样的测试用例中调用此任务
result = tasks.test_default_queue.apply_async(queue="install")

任务在队列install中成功运行(因为我在芹菜日志中看到它,它完成得很好。但我想知道以编程方式查找哪个队列是任务{{ 1}}从test_install_queue中存储的对象运行。

谢谢!

编辑:

我已将任务更改为:

result

然后我使用@app.task(name='test_install_queue',bind=True) def test_install_queue(self): return self.request.__dict__ 的结果如下:

apply_async

,解决方法是worker(hostname)与在worker中初始化的唯一队列具有相同的名称。

2 个答案:

答案 0 :(得分:5)

我本人只是面对过这个问题,我真的对是否需要像lexabug这样的复杂解决方案表示怀疑。 因此,由于即使Celery文档也没有提供有效的替代方法,所以我自己使用反射进行了调查,以便了解哪个对象包含了我所需的信息,并且我想到了一个超级简单易用的解决方案。具体来说,我用Celery术语编写了一个钩子,或者更好的信号,这就是我根据任务名称检索队列名称的方式:

    @signals.after_task_publish.connect()
    def on_task_publish(sender=None, headers=None, body=None, **kwargs):

        # "sender" is a string containing task name 
        # ("celery" here is the celery app)
        task: Task = celery.tasks.get(sender)

        # once we have the task object, we can access the "queue" property 
        # which contains the name of the queue 
        # (it' a dynamic property so don't expect support by your IDE)
        queue_name: str = task.queue if task is not None else 'unknown'

ps。我正在使用Celery 4.4

答案 1 :(得分:3)

您可以尝试以下方法:

delivery_info = app.current_task.request.delivery_info
# by default celery uses the same name for queues and exchanges
original_queue = delivery_info['exchange']
for queue in app.amqp.queues.itervalues():
    if queue.exchange.name == delivery_info['exchange'] 
        and queue.routing_key == delivery_info['routing_key']:
            original_queue = queue.name
            break

这种方法建立在您使用默认芹菜设置并且您的交换是直接的假设的基础上。如果您需要更多通用解决方案来进行扇出和主题交换,那么您必须在app.amqp.queues中检查每个已声明队列的路由键。