Opened 11 years ago

Closed 10 years ago

#19511 closed Bug (invalid)

Thread safe bound method weakrefs

Reported by: German M. Bravo Owned by: nobody
Component: Core (Other) Version: 1.4
Severity: Normal Keywords:
Cc: German M. Bravo Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm often getting this traceback:

AttributeError: 'BoundMethodWeakref' object has no attribute 'deletionMethods'

Stacktrace (most recent call last):

  File "django/core/handlers/base.py", line 119, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "posts/views.py", line 404, in get
    posts_post.save()
  File "django/db/models/base.py", line 475, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "django/db/models/base.py", line 506, in save_base
    signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using)
  File "django/dispatch/dispatcher.py", line 183, in send
    response = receiver(signal=self, sender=sender, **named)
  File "haystack/models.py", line 268, in load_indexes
    ui.setup_indexes()
  File "haystack/utils/loading.py", line 283, in setup_indexes
    index._setup_save()
  File "celery_haystack/indexes.py", line 33, in _setup_save
    signals.post_save.connect(self._enqueue_save, sender=model, dispatch_uid=CelerySearchIndex)
  File "django/dispatch/dispatcher.py", line 105, in connect
    receiver = saferef.safeRef(receiver, onDelete=self._remove_receiver)
  File "django/dispatch/saferef.py", line 29, in safeRef
    onDelete=onDelete
  File "django/dispatch/saferef.py", line 248, in get_bound_method_weakref
    return BoundMethodWeakref(target=target, onDelete=onDelete)
  File "django/dispatch/saferef.py", line 88, in __new__
    current.deletionMethods.append( onDelete)

I suspect this has something to do with the threading environment I'm using. I'm attaching a patch that I believe fixes the issue.

Attachments (2)

#19510-thread_safe_template_cache.diff (1.4 KB ) - added by German M. Bravo 11 years ago.
#19511-thread_safe_bound_method_weakref.diff (455 bytes ) - added by German M. Bravo 11 years ago.

Download all attachments as: .zip

Change History (9)

by German M. Bravo, 11 years ago

comment:1 by German M. Bravo, 11 years ago

Cc: German M. Bravo added

comment:2 by Florian Apolloner, 11 years ago

Resolution: fixed
Status: newclosed

Did you attach the wrong patch here?

comment:3 by Florian Apolloner, 11 years ago

Resolution: fixed
Status: closednew

Wth did the resolution get set to fixed :/

comment:4 by Aymeric Augustin, 11 years ago

Resolution: needsinfo
Status: newclosed

This may be a valid issue, but the description doesn't include enough information to reproduce it and the wrong patch was attached.

by German M. Bravo, 11 years ago

comment:5 by German M. Bravo, 11 years ago

Resolution: needsinfo
Status: closednew

Sorry I attached the wrong file, I've just attached the correct one.

The problem seems to be the BoundMethodWeakref._allInstances is filled with an uninitialised object, and when/if another thread tries to get and use the object right away, it doesn't still have at least the deletionMethods attribute which is added during the call to __init__().

Last edited 11 years ago by German M. Bravo (previous) (diff)

comment:6 by Anssi Kääriäinen, 11 years ago

Component: UncategorizedCore (Other)
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

The explanation seems correct to me. It also seems this will be impossible to test. You will need to switch to another thread in between the dict assignment and the __init__() call, and then you need to access the same key in another thread. An unlikely scenario.

comment:7 by Marc Tamlyn, 10 years ago

Resolution: invalid
Status: newclosed

Our implementation of weakrefs has now gone in favour of (backported) code from python 3.4. This should hopefully no longer be an issue.

Note: See TracTickets for help on using tickets.
Back to Top