Можно ли сериализовать Python объект с помощью pickle для передачи в Celery
Что проверяют
Различаете ли вы «технически поддерживается» и «так стоит делать», и понимаете ли, чем pickle опасен в распределённой системе. Заодно смотрят, представляете ли вы, что происходит с аргументами задачи между постановкой и выполнением.
Как отвечать
Да, Celery умеет pickle, но по умолчанию сериализатор json, и одной настройкой это не включается. Нужен и task_serializer, и accept_content на стороне воркера: воркер отвергает содержимое, тип которого не разрешён явно, и задача просто не выполнится.
Дальше объясните, почему список разрешённого вообще существует. Десериализация pickle это выполнение кода: тот, кто может положить сообщение в брокер, получает выполнение произвольного кода на всех воркерах. Открытый наружу брокер без пароля превращается в удалённый доступ ко всему кластеру. Если формат всё-таки нужен, Celery умеет подписывать сообщения, но чаще проще не передавать сложные объекты вовсе.
Рабочая схема: аргументы задачи это примитивы, сложное собирается уже внутри. Вместо объекта модели передают идентификатор и читают строку в самой задаче. К моменту выполнения данные могли измениться, а сессия, к которой объект был привязан, давно закрыта.
Где спотыкаются
Первое: обещают, что pickle сериализует что угодно. Открытые файлы и соединения, блокировки, генераторы, лямбды и вложенные функции не проходят, для них берут dill или cloudpickle.
Второе: не думают про выкатку. Pickle хранит путь к классу, и воркер обязан импортировать ровно тот же модуль. Переименовали класс или перенесли его в другой пакет, и сообщения, уже лежащие в очереди, прочитать не выйдет.
Третье: путают «безопасно» и «удобно». Совет разрешить pickle, чтобы не писать конвертеры, стоит дорого, а обратный переход на json болезненный: придётся разгрести все задачи, которые ходят объектами, и пережить период, когда в очереди лежат оба формата.