Celery и долгие задачи

Последнее время на проектах часто сталкиваюсь с celery-тасками, которые на момент написания обрабатывали небольшой объем данных, но со временем этот объем увеличивался и таска этого не ожидала. Например, у вас есть некая выборка пользователей которым нужно разослать письма, и со временем этот объем будет увеличиваться с приходом новых пользователей. Такие таски время от времени приходится переделывать на обработку больших объемов.

Предположим, у нас есть таск:

@task
def send_digest():
    users_to_send = User.objects.to_send_digest()
    for user in users_to_send:
        send_digest_email(user)

Один из вариантов - это увеличить время выполнения, но опять же это всего лишь временное решение. Мы будем разбивать наш массив на части и обрабатывать их, то есть мы будем брать первую часть, обрабатывать ее и ставить в очередь эту же таску со следующей порцией.

@task
def send_digest(offset=0, limit=0):
    users_to_send = User.objects.to_send_digest().order_by('id')[offset:offset + limit]
    for user in users_to_send:
        send_digest(user)

    if users_to_send.count() == limit:
        send_digest.delay(offset + limit, limit)

В конце мы проверяем количество объектов в массиве, если оно равно нашему лимиту, то скорее всего еще есть данные, если же количество меньше лимита, значит это была последняя порция.