Можете ли вы передать объект в задачу сельдерея по его идентификатору памяти с помощью ctypes? - PullRequest
1 голос
/ 31 октября 2019

Я хочу передать объект своего класса в задачу сельдерея. Я не использую Django, это мой собственный класс, который не сериализуем.

После исследования у меня появилась идея передать идентификатор памяти объекта в качестве аргумента, а затем получить объект из идентификатора согласно этот ответ :

tasks.py

import ctypes

@app.task
def my_task(obj_memory_id):
    my_obj = ctypes.cast(obj_memory_id, ctypes.py_object).value
    my_obj.my_method()

main.py

def main():
    obj = MyClass()
    obj_memory_id = id(obj)
    my_task.delay(obj_memory_id)

Теперь это работает, когда я выполняю это вне сельдерея. Но когда я делаю это с сельдереем, я получаю:

billiard.exceptions.WorkerLostError: Worker exited prematurely: signal 11 (SIGSEGV).

Почему это так и как я могу достичь своей цели?

Дополнительная информация: Я не являюсь экземпляромкласс внутри задачи Celery, потому что этот класс создается очень медленно (1-2 секунды). Для моих целей даже задержка в 1 секунду - это много. Я хочу, чтобы его экземпляр был готов заранее, а когда мне нужно вызвать его метод, сделать это немедленно.

1 Ответ

2 голосов
/ 31 октября 2019

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

Вам нужно каким-то образом сделать сериализуемый объект, если вы хотите использовать Celery полезным способом. Либо сделав его маринованным, либо что-то лучше.

...