"""Reacts to an admin editing a PlaceSettings row (grid size, end time) by: 1. Rebuilding that event's Redis canvas from history at the (possibly new) dimensions - a resize invalidates the old Redis bytes (wrong length, wrong meaning), so this keeps Redis self-healing instead of relying on the admin remembering to click "Resync canvas from DB" after every resize. 2. Pushing the new settings to that event's already-connected clients. Unlike the clock app, place has no periodic heartbeat broadcast to piggyback this onto, so it's broadcast explicitly here instead. 3. Queueing the wipe for the end time, if any (see tasks.py). """ from asgiref.sync import async_to_sync from channels.layers import get_channel_layer from django.db.models.signals import post_save from django.dispatch import receiver from .broadcast import place_group from .canvas import rebuild_canvas_from_history from .models import PlaceSettings from .tasks import schedule_wipe from .wire import to_epoch_ms @receiver(post_save, sender=PlaceSettings) def on_settings_saved(sender, instance, **kwargs): rebuild_canvas_from_history(instance.event, instance.width, instance.height) schedule_wipe(instance) channel_layer = get_channel_layer() if channel_layer is None: return async_to_sync(channel_layer.group_send)( place_group(instance.event.path), { "type": "settings_changed", "width": instance.width, "height": instance.height, "ends_at": ( None if instance.placement_ends_at is None else to_epoch_ms(instance.placement_ends_at) ), }, )