Skip to content

Commit

Permalink
fix: ConfigWatcher needs to register receivers using strong references
Browse files Browse the repository at this point in the history
These inner functions would otherwise get GC'd right away, since Django
only holds weak references to receivers by default.
  • Loading branch information
timmc-edx committed Nov 6, 2023
1 parent cf0527f commit 88dab7a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Change Log
Unreleased
~~~~~~~~~~

[3.1.1] - 2023-11-06
~~~~~~~~~~~~~~~~~~~~
Fixed
_____
* ConfigWatcher should now respond to model events properly now that it registers receivers with strong references. (Tested in sandbox.)

[3.1.0] - 2023-10-31
~~~~~~~~~~~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion edx_arch_experiments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
A plugin to include applications under development by the architecture team at 2U.
"""

__version__ = '3.1.0'
__version__ = '3.1.1'
13 changes: 11 additions & 2 deletions edx_arch_experiments/config_watcher/signals/receivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,24 @@ def _register_waffle_observation(*, model, short_name, fields):
short_name (str): A short descriptive name for an instance of the model, e.g. "flag"
fields (list): Names of fields to report on in the Slack message
"""
@receiver(signals.post_save, sender=model, dispatch_uid=f"config_watcher_{short_name}_change")

# Note that weak=False is required here. Django by default only
# holds weak references to receiver functions. But these inner
# functions would then be garbage-collected, and Django would drop
# them. So pass weak=False to make Django hold strong references
# instead. (It works either way in devstack, apparently due to an
# interaction with settings.DEBUG causing a reference to be held:
# <https://stackoverflow.com/a/70651310>.)

@receiver(signals.post_save, sender=model, weak=False, dispatch_uid=f"config_watcher_{short_name}_change")
def report_waffle_change(*args, instance, created, **kwargs):
try:
_report_waffle_change(short_name, instance, created, fields)
except: # noqa pylint: disable=bare-except
# Log and suppress error so Waffle change can proceed
log.exception(f"Failed to report change to waffle {short_name}")

@receiver(signals.post_delete, sender=model, dispatch_uid=f"config_watcher_{short_name}_delete")
@receiver(signals.post_delete, sender=model, weak=False, dispatch_uid=f"config_watcher_{short_name}_delete")
def report_waffle_delete(*args, instance, **kwargs):
try:
_report_waffle_delete(short_name, instance)
Expand Down

0 comments on commit 88dab7a

Please sign in to comment.