当我使用Djang Celery apply_async和eta时,它会立即完成工作

时间:2017-07-13 14:39:19

标签: python django celery django-celery celery-task

我查看了芹菜文档并尝试了一些东西,但它不像示例那样工作。也许我在某些方面错了,如果我对以下代码的错误,请给我一些指针

在views.py中我有类似的东西:

class Something(CreateView):
  model = something

  def form_valid(self, form):
    obj = form.save(commit=False)
    number = 5
    test_limit = datetime.now() + timedelta(minutes=5)
    testing_something.apply_async((obj, number), eta=test_limit)
    obj.save()

在芹菜任务中我写了这样的东西:

@shared_task()
def add_number(obj, number):
    base = Base.objects.get(id=1)
    base.add = base.number + number
    base.save()
return obj

我使用此代码的条件是芹菜在CreateView运行后立即运行,我的目标是在运行Something CreateView后的5分钟内运行任务add_number。非常感谢你

修改:

  1. 我尝试将eta更改为countdown=180,但它仍然立即运行功能add_number。我也尝试了更长的倒计时但仍然立即运行
  2. 我已经尝试了@johnmoustafis回答,但仍然相同,任务立即运行
  3. 我也试过@dana的答案,但它仍然一样,任务立即运行

3 个答案:

答案 0 :(得分:1)

Celery默认使用UTC时间 如果您的时区“UTC”(UTC - HH:MM)“后面”,datetime.now()调用将返回一个“落后”UTC的时间戳,从而导致您的任务立即执行。

您可以改为使用datetime.utcnow()

test_limit = datetime.utcnow() + timedelta(minutes=5)

由于您使用的是django,因此存在另一种选择:

如果您在USE_TZ = True中设置了setting.py,则表示您启用了django timezone settings,并且您可以使用timezone.now()代替datetime.utcnow()

from django.utils import timezone

...

test_limit = timezone.now() + timedelta(minutes=5)

答案 1 :(得分:0)

您可能拥有CELERY_ALWAYS_EAGER=True设置。

您是否还可以发布您正在使用的配置和Celery版本?

Here您可能会找到一些有用的信息。

答案 2 :(得分:0)

' test_limit'变量还没有时区信息。所以Celery会将eta param理解为UTC时间。

请使用修改后的代码:

class Something(CreateView):
    model = something

    def form_valid(self, form):
        obj = form.save(commit=False)
        number = 5

        test_limit = datetime.now()
        test_limit = test_limit.replace(tzinfo=tz.tzlocal())
        test_limit = test_limit + timedelta(minutes=5)

        testing_something.apply_async((obj, number), eta=test_limit)
        obj.save()