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)
В конце мы проверяем количество объектов в массиве, если оно равно нашему лимиту, то скорее всего еще есть данные, если же количество меньше лимита, значит это была последняя порция.