如何在另一个Celery任务中获取Celery任务的结果?

时间:2020-09-02 12:52:28

标签: python celery

请原谅我的无知,因为我正在学习如何将芹菜用于我的目的。

假设我有两个任务:create_ticketadd_message_to_ticket。通常create_ticket任务是在多次创建add_message_to_ticket任务之前创建和完成的。

@app.task
def create_ticket(ticket_id):
    time.sleep(random.uniform(1.0, 4.0)) # replace with code that processes ticket creation
    return f"Successfully processed ticket creation: {ticket_id}"

@app.task
def add_message_to_ticket(ticket_id, who, when, message_contents):
    # TODO add code that checks to see if create_ticket task for ticket_id has already been completed
    time.sleep(random.uniform(1.0, 4.0)) # replace with code that handles added message
    return f"Successfully processed message for ticket {ticket_id} by {who} at {when}"

现在,由于Python的服务器从外部Web服务无序接收事件,因此假设这些任务是无序创建的。例如,一个add_message_to_ticket.delay(82, "auroranil", 1599039427, "This issue also occurs on Microsoft Edge on Windows 10.")在被调用create_ticket.delay(82)之前几秒钟被调用。我该如何解决以下问题?

  1. 如何通过在任务create_ticket中指定ticket_id来获取芹菜任务add_message_to_ticket的结果?我能想到的就是维护一个存储票证状态的数据库,并检查是否已创建特定票证,但是我想知道我是否能够以某种方式使用celery的结果后端。
  2. 如果我收到一个带有工单ID的add_message_to_ticket任务,发现对应的工单尚未完成create_ticket任务,我是否会拒绝该任务并将其放回队列中? / li>
  3. 我需要确保任务是幂等的吗?我知道这是个好习惯,但这是否是必须的?
  4. 是否有更好的方法来解决此问题?我知道Celery Canvas工作流具有诸如链之类的原语,但是我不确定如何确保这些事件按顺序处理,或者在等待依赖于其完成的任务时如何将任务置于待处理状态基于我想让celery检查的参数,在这种情况下为ticket_id

如果接收到某个特定故障单的多个用户消息时时间戳不正确,我并不特别担心,因为这与在将消息添加到该故障单之前知道已创建故障单并不重要。我要说的是,我正在编写一些任务,其中某些事件严重依赖于其他事件,而其他事件的顺序对Python服务器的功能并没有多大影响。

编辑:

部分解决方案:

  • 使用task_id来标识Celery任务,其格式字符串包含标识该任务的参数值。例如,task_id="create_ticket(\"TICKET000001\")"
  • 重试不满足依赖项要求的任务。阻止子任务完成很不好,因为子任务可能永远不会完成,并且会在其中一台工作计算机上占用一个进程。
  • 将参数存储为已完成任务的结果的一部分,以便您可以使用以后的任务中不可用的信息。

相关链接:

更多问题:

  • 如何确保每个task_id?发送一次任务,例如,我希望create_ticket任务仅异步应用一次。这是使所有任务成为幂等的替代方法。
  • 如何使用AsyncResult中的add_message_to_ticket检查create_ticket任务的状态?即使第一个任务可能已经完成,也可以以某种方式指定一条链吗?
  • 在给定任务名称的情况下,如何从函数定义名称中获取任务的所有结果?
  • 最重要的是,我应该使用Celery结果后端从存储的数据中提取抽象的数据吗?还是我应该放弃这个想法,而直接设计数据库架构?

0 个答案:

没有答案
相关问题