Какие ограничения есть при передаче объектов в задачи Celery
Что проверяют
Помните ли, что аргумент задачи это сообщение, а не ссылка на объект: оно сериализуется, летит через брокер и оживает в другом процессе, возможно через час и на другой машине. Уточняющий вопрос обычно про Django-модель: почему её не стоит передавать целиком.
Как отвечать
Начните с сериализации. С Celery 4 сериализатор по умолчанию это JSON (task_serializer, result_serializer, accept_content). Значит, аргументы ограничены типами JSON: числа, строки, булевы, списки, словари, None. Кодировщик kombu дополнительно умеет datetime, date, UUID и Decimal, а set, bytes и свой класс придётся приводить к словарю руками.
- что не передаётся в принципе: открытые соединения, файловые объекты, сессия ORM, лямбды и локальные функции, генераторы. Вне своего процесса они не имеют смысла;
- pickle: снимает ограничения по типам, но исполняет код при десериализации. Кто может писать в очередь, получает выполнение кода на воркере, поэтому включать его допустимо только в доверенном контуре;
- размер: сообщение целиком лежит в брокере, а результат в бэкенде. Держите аргументы в килобайтах, а датафрейм или файл кладите в объектное хранилище и передавайте ключ;
- актуальность данных: передавайте идентификатор, а не объект. Пока задача ждёт в очереди, запись меняется, и воркер отработает по устаревшей копии;
- возвращаемое значение: подчиняется тем же правилам и живёт в бэкенде ограниченное время (
result_expires, по умолчанию сутки).
Отдельно про Django: task.delay(obj.pk) внутри транзакции приводит к тому, что воркер лезет в базу раньше коммита и не находит строку. Ставьте задачу через transaction.on_commit.
Где спотыкаются
Передают объект целиком, ловят EncodeError и вместо разбора причины переключают проект на pickle. Гонка данных остаётся, а дыра в безопасности добавляется.
Забывают, что доставка идёт как минимум один раз: при acks_late и перезапуске воркера задача выполнится повторно. Поэтому «списать 100 рублей» без ключа операции в аргументах быть не должно.
Кладут в аргументы пароли, токены и персональные данные. Всё это видно в очереди, во Flower и в логах, а в брокере лежит открытым текстом.