django-q2 icon indicating copy to clipboard operation
django-q2 copied to clipboard

Getting "TypeError: cannot pickle '_thread.RLock' object" error when trying to send emails using AsyncTask

Open oussama-he opened this issue 10 months ago • 2 comments

I can this error when trying to use django-q2 package when sending emails:

INFO 2024-04-06 14:33:40,148 worker 22676 127007069675520 Process-0b549de9691d49f9b9dd40206f0ff9cf processing delaware-uranus-lemon-seventeen '<bound method EmailMessage.send of <django.core.mail.message.EmailMultiAlternatives object at 0x73831f582440>>' [email]
Traceback (most recent call last):
  File "/usr/lib/python3.10/multiprocessing/queues.py", line 244, in _feed
    obj = _ForkingPickler.dumps(obj)
  File "/usr/lib/python3.10/multiprocessing/reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: cannot pickle '_thread.RLock' object

My code looks like this:

        with get_connection(
            host=settings.EMAIL_HOST,
            port=settings.EMAIL_PORT,
            username=settings.EMAIL_HOST_USER,
            password=settings.EMAIL_HOST_PASSWORD,
            use_tls=True,
        ) as connection:
            subject = data["subject"]
            body = data["message"]
            recipient = data["recipient"]
            email = EmailMultiAlternatives(
                subject=subject,
                body=body,
                from_email=settings.DEFAULT_FROM_EMAIL,
                to=[recipient],
            )
            message = prepare_message(subject, body)
            email.attach_alternative(message, "text/html")
            a = AsyncTask(email.send, group="email")
            a.run()

When I tried this, it worked fine without error:

a = AsyncTask('math.floor', 1.5, group="math")
a.run()

Also, I tried to send email without using AsyncTask and it worked fine also.

I'm using Python 3.10.12, Django 4.2.11, and django-q2 1.6.2.

Do you have any idea about this problem or how can fix it?

Let me know if I should provide more code/details.

oussama-he avatar Apr 06 '24 11:04 oussama-he

It's sometimes tricky to pickle functions based on objects and can lead to errors. Pickling works best for standard things, like arrays, strings, integers... I would suggest moving the whole email sending thing into a separate function and triggering that through AsyncTask.

GDay avatar Apr 06 '24 21:04 GDay

It's sometimes tricky to pickle functions based on objects and can lead to errors. Pickling works best for standard things, like arrays, strings, integers... I would suggest moving the whole email sending thing into a separate function and triggering that through AsyncTask.

That worked for me. Thanks!

jv3ga avatar May 14 '24 08:05 jv3ga