如何按名称调用Celery任务

时间:2015-05-18 16:19:51

标签: python-2.7 celery

我们有一个使用Celery的Python应用程序,RabbitMQ作为Broker。将此应用程序视为管理应用程序,只将消息/任务放入Broker中,并且不会对它们采取行动。

将会有另一个应用程序(可能是基于Python,也可能不是基于Python),它将对消息采取行动。

当管理应用程序在其代码库中不存在该任务时,是否有可能将消息/任务放在队列上?如果是这样,我该怎么做呢?

3 个答案:

答案 0 :(得分:4)

您可以使用AMQP客户端向队列发送新消息,可以在rabbitMQ docs中找到现有列表。

如何做真的取决于你将使用哪种客户端和语言,但原则上一切都是发送符合芹菜正在使用的协议的消息:

with Connection("my_broker_url") as connection:
    queue = connection.SimpleQueue(queue_name)
    message = {"id": "4cc7438e-afd4-4f8f-a2f3-f46567e7ca77",
               "task": "celery.task.PingTask",
               "args": [],
               "kwargs": {},
               "retries": 0,
               "eta": "2009-11-17T12:30:56.527191"}
    queue.put(message,
              serializer="json")

您可以在芹菜文档here中找到有关消息的更详细说明。

例如,如果使用kombu客户端(也是芹菜使用的python),你会做这样的事情:

POST /api/task/send-task/tasks.add HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, compress
Content-Length: 16
Content-Type: application/json; charset=utf-8
Host: localhost:5555

{
    "args": [1, 2]
}

这是kombu docs

中一个高度剥离的示例

经过一番搜索后跟进

所以我完全忘记提及flower,这是芹菜的一个很棒的监控和管理工具。它作为守护进程运行,并公开Web界面和漂亮的Rest API!

我发现你可以从花卉API发送任务,就像这样简单:

send-task

有一些API端点允许您这样做,但存在一些差异:

但在这种情况下,您可能希望用户{{1}},因为它明确声明您不需要具有该任务源。{/ p>

希望这有帮助!

答案 1 :(得分:4)

还有更多" Celery-esque"称为Signatures的方式。设置指向同一代理的Celery应用程序并为您的任务创建签名:

from celery import Celery

celeryapp = Celery(...)

my_task = celeryapp.signature('task.add')
result = my_task.delay(2, 2)
print result.get()

答案 2 :(得分:2)

  1. 创建Celery的新实例或从模块导入。
  2. 调用send_task()方法。

    from twittershell.core import app # Celery Instance from a module
    async_result = app.send_task(name='tasks.followers', args=(529675892, ))
    
  3. send_task方法的签名是:

        def send_task(self, name, args=None, kwargs=None, countdown=None,
                  eta=None, task_id=None, producer=None, connection=None,
                  router=None, result_cls=None, expires=None,
                  publisher=None, link=None, link_error=None,
                  add_to_parent=True, reply_to=None, **options):