4

I want to pass a object of my own class to a celery task. I am not using Django, this is my own custom class which is not serializable.

After researching, I got the idea to pass the object memory id as an argument and then get the object from the id as per this answer:

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)

Now, this works when I perform it outside celery. But when I do it with celery, I get:

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

Why is that and how can I achieve my goal?

More info: I am not instantiating the class inside the Celery task, because this class instantiates very slow (1-2 seconds). For my purposes, even a delay of 1 second is a lot. I want to have its instance ready in advance, and when I need to call its method, to do it immediately.

Nikolay Shindarov
  • 1,616
  • 2
  • 18
  • 25

1 Answers1

3

The celery worker runs in a different process, potentially on a different machine. It is unlikely to share memory with the process that spawns the task. You are passing a random pointer to the task, that task dereferences it and you get garbage.

You need to make your object serializable in some way if you want to use Celery in a useful way. Either by making it pickleable or something better.

Markus Unterwaditzer
  • 7,992
  • 32
  • 60