Opened 4 years ago

Closed 3 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 4 years ago.
#19511-thread_safe_bound_method_weakref.diff (455 bytes) - added by German M. Bravo 4 years ago.

Download all attachments as: .zip

Change History (9)

Changed 4 years ago by German M. Bravo

comment:1 Changed 4 years ago by German M. Bravo

Cc: German M. Bravo added
Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

comment:2 Changed 4 years ago by Florian Apolloner

Resolution: fixed
Status: newclosed

Did you attach the wrong patch here?

comment:3 Changed 4 years ago by Florian Apolloner

Resolution: fixed
Status: closednew

Wth did the resolution get set to fixed :/

comment:4 Changed 4 years ago by Aymeric Augustin

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.

Changed 4 years ago by German M. Bravo

comment:5 Changed 4 years ago by German M. Bravo

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, it doesn't still have at least the deletionMethods attribute which is added durin the call to __init__().

Version 0, edited 4 years ago by German M. Bravo (next)

comment:6 Changed 4 years ago by Anssi Kääriäinen

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 Changed 3 years ago by Marc Tamlyn

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