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. (I don't know why this
worked in devstack.)
  • Loading branch information
timmc-edx committed Nov 3, 2023
1 parent cf0527f commit af32b75
Show file tree
Hide file tree
Showing 3 changed files with 16 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'
11 changes: 9 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,22 @@ 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. (For some reason, this isn't needed in devstack...)

@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 af32b75

Please sign in to comment.