Code

Opened 3 years ago

Closed 3 years ago

#17029 closed Bug (wontfix)

django.dispatch.dispatcher.Signal should be pickleable

Reported by: d0ugal Owned by: nobody
Component: Core (Other) Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

The Signal class contains an instance of threading.Lock which means it can't be pickled without providing pickle with some hints. It should be pickleable as it is passed in the kwargs to signal receivers, the use case that requires all arguments to be pickleable is best demonstrated as follows.

This example uses a celery task as the receiver of a signal to in effect provide "async signals" which would allow for some nice patterns to be developed.

# In a models.py file in any project with celery already configured.
from celery.task import task
from django.db import models
from django.db.models.signals import pre_delete, pre_save

class MyModel(models.Model):
    pass

@task(ignore_result=True)
def async_post_save(sender, instance, **kwargs):
    # do something with the instance.
    pass

post_save.connect(async_post_save.delay, sender=MyModel)

I've attached a patch for this which basically implements a very small monkey patch that I am currently using in a project.

from django.dispatch.dispatcher import Signal
def reducer(self):
    return (Signal, (self.providing_args,))
Signal.__reduce__ = reducer

As it happens, I quickly threw together a blog post about this trick: http://dougalmatthews.com/2011/10/10/making-django's-signals-asynchronous-with-celery/

Attachments (1)

pickled_signal.diff (1.8 KB) - added by d0ugal 3 years ago.

Download all attachments as: .zip

Change History (3)

Changed 3 years ago by d0ugal

comment:1 Changed 3 years ago by gtaylor

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Very neat idea. We'd like this very much.

comment:2 Changed 3 years ago by Alex

  • Resolution set to wontfix
  • Status changed from new to closed

After speaking with Carl, I'm marking this as wontfix because it is non-obvious as to whether pickling a Signal should include the registered receivers, and how that interacts with the weak referencing, since there's no obvious semantic it seems better not to guess.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.