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
#495)

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 authored Nov 6, 2023
1 parent cf0527f commit 729fd8d
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 729fd8d

Please sign in to comment.