Задача Celery вызывается три раза, но данные, поставляемые для задачи, не меняются - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть модель документа с FileField для загрузки изображений, pdfs и т. Д. c. И ImageFields для восьми различных размеров изображений, созданных из одного загруженного файла. Я преобразую загруженное изображение в 8 различных размеров, используя подушку. Я разрешаю многократную загрузку файлов в DocumentAdmin, и в save_model я создаю миниатюру и большое изображение для отображения на странице DocumentAdmin, а затем использую задачу сельдерея (с перенаправлением), чтобы создать другие фоновые изображения других размеров и сохранить их в фоновом режиме. модель документа.

Мой код правильно создает разные изображения, но у меня, похоже, странная ситуация с задачей сельдерея. Задача celery использует тот же код для создания изображений разных размеров, что и код, используемый в save_model для создания большого и большого изображения.

Соответствующая часть кода save_model:

def save_model(self, request, obj, form, change):
    if form.is_valid():
        if not change:
            # Uploading one or more images
            files = request.FILES.getlist('storage_file_name')
            if files:
                for f in files:
                    with transaction.atomic():
                        original_file_name, extension = os.path.splitext(f.name)
                        new_file_name = original_file_name + "." + settings.DEFAULT_IMAGE_EXTENSION
                        obj2 = Document()
                        # save the original file
                        if extension.lower() == ".pdf":
                        obj2.pdf_file = f
                        else:
                            obj2.storage_file_name = f
                        save_document_images(obj2, new_file_name, image_file=f, rot_angle=0, thumbnail=True, xsmall=False, small=False, medium=False, large=True, xlarge=False, xxlarge=False, xxxlarge=False)
                        obj2.save()
                        logger.debug("Starting transaction for document-id=%s, new_file_name=%s" % (obj2.document_id, new_file_name))
                        transaction.on_commit(lambda: tasks.create_additional_images_task.apply_async(args=[obj2.document_id, new_file_name,], kwargs={'rot_angle':0, 'thumbnail': False, 'xsmall':True, 'small':True, 'medium':True, 'large':False, 'xlarge':True, 'xxlarge':True, 'xxxlarge':True})) 

И код для задания сельдерея:

@app.task(bind=True)
def create_additional_images_task(self, *args, **kwargs):
    from memorabilia.models import Document
    obj2 = Document.objects.get(document_id=args[0])
    image_file = obj2.storage_file_name
    clogger.debug("document_id=%s, obj2=%s, new_file_name=%s, image_file=%s" % (args[0], obj2, args[1], image_file.name))
    for key in kwargs:
        clogger.debug("kwargs: key=%s, value=%s" % (key, kwargs[key]))
    save_document_images(obj2, args[1], image_file, kwargs['rot_angle'], kwargs['thumbnail'], kwargs['xsmall'], kwargs['small'], kwargs['medium'], kwargs['large'], kwargs['xlarge'], kwargs['xxlarge'], kwargs['xxxlarge']) 

Например, я загружаю три разных изображения. Когда я просматриваю журналы Django, я вижу, что задача сельдерея вызывается три раза с тремя разными document_ids и именами изображений:

[2020-04-19 17:10:18] DEBUG [memorabilia.admin.save_model:1739] Starting transaction for document-id=110, new_file_name=image-1.jpg
[2020-04-19 17:10:19] DEBUG [memorabilia.admin.save_model:1739] Starting transaction for document-id=111, new_file_name=image-2.jpg
[2020-04-19 17:10:20] DEBUG [memorabilia.admin.save_model:1739] Starting transaction for document-id=112, new_file_name=image-3.jpg

Когда я просматриваю журнал сельдерея, я вижу следующее:

[2020-04-19 17:10:20,665: INFO/MainProcess] Received task: memorabilia.tasks.create_additional_images_task[ec7699d8-7b73-4004-bb78-9371bcf0e1d6]  
[2020-04-19 17:10:20,666: DEBUG/MainProcess] TaskPool: Apply <function _fast_trace_task at 0x7f85ce09ae18> (args:('memorabilia.tasks.create_additional_images_task', 'ec7699d8-7b73-4004-bb78-9371bcf0e1d6', {'lang': 'py', 'task': 'memorabilia.tasks.create_additional_images_task', 'id': 'ec7699d8-7b73-4004-bb78-9371bcf0e1d6', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': 'ec7699d8-7b73-4004-bb78-9371bcf0e1d6', 'parent_id': None, 'argsrepr': "[112, 'image-3.jpg']", 'kwargsrepr': "{'rot_angle': 0, 'thumbnail': False, 'xsmall': True, 'small': True, 'medium': True, 'large': False, 'xlarge': True, 'xxlarge': True, 'xxxlarge': True}", 'origin': 'gen18286@tsunami', 'reply_to': '9dc88644-e203-30ff-a643-a14314f2572a', 'correlation_id': 'ec7699d8-7b73-4004-bb78-9371bcf0e1d6', 'delivery_info': {'exchange': '', 'routing_key': 'celery', 'priority': 0, 'redelivered': None}}, b'[[112, "image-3.jpg"], {"rot_angle": 0, "thumbnail": false, "xsmall": true, "small": true, "medium": true, "large": false, "xlarge": true, "xxlarge": true, "xxxlarge": true}, {"callbacks": null,... kwargs:{})

[2020-04-19 17:10:20,667: INFO/MainProcess] Received task: memorabilia.tasks.create_additional_images_task[eeb2ac99-ae1f-4530-9e41-fe923cfba912]  
[2020-04-19 17:10:20,667: DEBUG/MainProcess] TaskPool: Apply <function _fast_trace_task at 0x7f85ce09ae18> (args:('memorabilia.tasks.create_additional_images_task', 'eeb2ac99-ae1f-4530-9e41-fe923cfba912', {'lang': 'py', 'task': 'memorabilia.tasks.create_additional_images_task', 'id': 'eeb2ac99-ae1f-4530-9e41-fe923cfba912', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': 'eeb2ac99-ae1f-4530-9e41-fe923cfba912', 'parent_id': None, 'argsrepr': "[112, 'image-3.jpg']", 'kwargsrepr': "{'rot_angle': 0, 'thumbnail': False, 'xsmall': True, 'small': True, 'medium': True, 'large': False, 'xlarge': True, 'xxlarge': True, 'xxxlarge': True}", 'origin': 'gen18286@tsunami', 'reply_to': '9dc88644-e203-30ff-a643-a14314f2572a', 'correlation_id': 'eeb2ac99-ae1f-4530-9e41-fe923cfba912', 'delivery_info': {'exchange': '', 'routing_key': 'celery', 'priority': 0, 'redelivered': None}}, b'[[112, "image-3.jpg"], {"rot_angle": 0, "thumbnail": false, "xsmall": true, "small": true, "medium": true, "large": false, "xlarge": true, "xxlarge": true, "xxxlarge": true}, {"callbacks": null,... kwargs:{})

[2020-04-19 17:10:20,668: INFO/MainProcess] Received task: memorabilia.tasks.create_additional_images_task[04cb7f54-285d-4e0f-86e0-aaa2995d1cb4]  
[2020-04-19 17:10:20,669: DEBUG/MainProcess] TaskPool: Apply <function _fast_trace_task at 0x7f85ce09ae18> (args:('memorabilia.tasks.create_additional_images_task', '04cb7f54-285d-4e0f-86e0-aaa2995d1cb4', {'lang': 'py', 'task': 'memorabilia.tasks.create_additional_images_task', 'id': '04cb7f54-285d-4e0f-86e0-aaa2995d1cb4', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': '04cb7f54-285d-4e0f-86e0-aaa2995d1cb4', 'parent_id': None, 'argsrepr': "[112, 'image-3.jpg']", 'kwargsrepr': "{'rot_angle': 0, 'thumbnail': False, 'xsmall': True, 'small': True, 'medium': True, 'large': False, 'xlarge': True, 'xxlarge': True, 'xxxlarge': True}", 'origin': 'gen18286@tsunami', 'reply_to': '9dc88644-e203-30ff-a643-a14314f2572a', 'correlation_id': '04cb7f54-285d-4e0f-86e0-aaa2995d1cb4', 'delivery_info': {'exchange': '', 'routing_key': 'celery', 'priority': 0, 'redelivered': None}}, b'[[112, "image-3.jpg"], {"rot_angle": 0, "thumbnail": false, "xsmall": true, "small": true, "medium": true, "large": false, "xlarge": true, "xxlarge": true, "xxxlarge": true}, {"callbacks": null,... kwargs:{})

Создано три задачи (1d6, 912, cb4 - использовать последние три цифры идентификатора задачи). Однако все три задачи имеют в качестве аргументов [112, "image-3.jpg"] (document_id = 112, file_name = image-3jpg) Когда я смотрю на файловую систему, я вижу, что изображения, которые должна иметь задача сельдерея сделанные для document_id 110 и 111 не были сделаны, но были созданы изображения для document_id 112. Миниатюра и большое изображение для всех трех document_ids были созданы, поэтому кажется, что код для создания изображений работает.

Что я делаю неправильно в своем коде? Должен признаться, это мой первый опыт использования сельдерея, поэтому я немного растерялся.

Спасибо!

Марк

1 Ответ

0 голосов
/ 20 апреля 2020

1) Я бы сказал, что вы используете on_commit неправильно. Согласно документации, он должен был выглядеть как

for f in files:
    with transaction.atomic():
        transaction.on_commit(...)

Иначе как Django знать, к какой транзакции относятся эти on_commit? Итак, вы добавили три изображения, сохраните их, и это одна транзакция с тремя слушателями.

2) Пожалуйста, не используйте одинаковые import в for операторах. Просто переместите его выше, прежде чем for

...