Выполнение «уникальных» задач с сельдереем

Я использую сельдерей для обновления RSS-каналов на моем сайте агрегации новостей. Я использую одну @task для каждого канала, и, похоже, все работает нормально.

Есть деталь, с которой я не уверен, что с ней справлюсь: все каналы обновляются раз в минуту с помощью @periodic_task, но что, если канал все еще обновляется после последней периодической задачи при запуске новой? (например, если поток очень медленный или отключен, а задача удерживается в цикле повтора)

В настоящее время я храню результаты задач и проверяю их статус следующим образом:

import socket
from datetime import timedelta
from celery.decorators import task, periodic_task
from aggregator.models import Feed


_results = {}


@periodic_task(run_every=timedelta(minutes=1))
def fetch_articles():
    for feed in Feed.objects.all():
        if feed.pk in _results:
            if not _results[feed.pk].ready():
                # The task is not finished yet
                continue
        _results[feed.pk] = update_feed.delay(feed)


@task()
def update_feed(feed):
    try:
        feed.fetch_articles()
    except socket.error, exc:
        update_feed.retry(args=[feed], exc=exc)

Может быть, есть более сложный / надежный способ достижения того же результата, используя какой-нибудь сельдерейный механизм, который я пропустил?

48
задан Luper Rouch 16 October 2017 в 18:24
поделиться