0

我有一个 Django 休息框架应用程序,它在序列化程序创建方法中连续调用 2 个 Huey 任务,如下所示:

...
def create(self, validated_data):
    user = self.context['request'].user
    player_ids = validated_data.get('players', [])
    game = Game.objects.create()

    tasks.make_players_friends_task(player_ids)
    tasks.send_notification_task(user.id, game.id)
    return game

# tasks.py
@db_task()
def make_players_friends_task(ids):
    players = User.objects.filter(id__in=ids)
    # process players

@db_task()
def send_notification_task(user_id, game_id):
    user = User.objects.get(id=user_id)
    game = Game.objects.get(id=game_id)
    # send notifications

在终端中运行 huey 进程时,当我点击这个端点时,我可以看到只有一个或另一个任务被调用,但从来没有两个。我正在使用默认设置运行 huey(带有 1 个线程工作者的 redis。)

如果我更改代码以便将对象本身作为参数而不是 ids 传递,并删除@db_task方法中的 django 查询,事情似乎工作正常。

我最初使用 ids 作为参数的原因是因为我假设(或在某处读到)huey 使用 json 序列化作为默认值,但在研究之后,pickle它实际上是默认序列化程序。

一种理论是,由于我只运行一个工作者,并且@db_periodic_task在应用程序中也有一个方法,因此该进程只能处理侦听任务或随时执行它们,但不能同时处理两者。这就是 celery 的工作方式,您需要为调度程序和工作人员分别设置一个单独的进程,但这在 huey 的文档中没有提到。

4

1 回答 1

0

如果您运行 huey 消费者,它实际上会生成一个单独的调度程序以及您指定的工作人员数量,所以这不会是您的问题。

您没有提供足够的信息来实际正确查看问题所在,因此请检查以下内容:

  • 如果您在终端中运行 huey 消费者,请观察您的所有任务是否显示为正确注册,以便消费者实际上能够使用它们。
  • 检查你的redis进程是否正在运行。
  • 尝试使用阻塞调用执行任务,以查看失败的任务:

    task_result = tasks.make_players_friends_task(player_ids)
    task_result.get(blocking=True)
    task_result = tasks.send_notification_task(user.id, game.id)
    task_result.get(blocking=True)
    

    使用调试器或打印语句执行此操作,以查看它是否到达函数的末尾或卡在哪里。

  • 确保在更改代码时始终重新启动您的使用者。它不会像 django 开发服务器那样自动获取新代码。您的代码在腌制整个对象而不是传递 id 时按预期工作的事实可能指向这一点,因为这会破坏它真的很奇怪。另一方面,您不应该传入 django ORM 对象。使用您的 id 方法更有意义。

于 2020-04-02T22:01:54.257 回答