Skip to content

Commit a2e6304

Browse files
committed
Fixes: #15194 - Check the whole queue for matching queued webhooks
1 parent c21ec21 commit a2e6304

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

netbox/extras/signals.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,21 @@
3030
clear_events = Signal()
3131

3232

33-
def is_same_object(instance, webhook_data, request_id):
33+
def last_matching_index(instance, queue, request_id):
3434
"""
35-
Compare the given instance to the most recent queued webhook object, returning True
36-
if they match. This check is used to avoid creating duplicate webhook entries.
35+
Find the latest queued webhook object matching the given instance, returning its index.
36+
If no object is found, return None. This check is used to avoid creating duplicate webhook
37+
entries.
3738
"""
38-
return (
39-
ContentType.objects.get_for_model(instance) == webhook_data['content_type'] and
40-
instance.pk == webhook_data['object_id'] and
41-
request_id == webhook_data['request_id']
42-
)
39+
try:
40+
return max(
41+
index_ for index_, webhook_data in enumerate(queue)
42+
if ContentType.objects.get_for_model(instance) == webhook_data['content_type'] and
43+
instance.pk == webhook_data['object_id'] and
44+
request_id == webhook_data['request_id']
45+
)
46+
except ValueError:
47+
return None
4348

4449

4550
@receiver((post_save, m2m_changed))
@@ -89,10 +94,10 @@ def handle_changed_object(sender, instance, **kwargs):
8994

9095
# If this is an M2M change, update the previously queued webhook (from post_save)
9196
queue = events_queue.get()
92-
if m2m_changed and queue and is_same_object(instance, queue[-1], request.id):
97+
if m2m_changed and queue and (last_index := last_matching_index(instance, queue, request.id)) is not None:
9398
instance.refresh_from_db() # Ensure that we're working with fresh M2M assignments
94-
queue[-1]['data'] = serialize_for_event(instance)
95-
queue[-1]['snapshots']['postchange'] = get_snapshots(instance, action)['postchange']
99+
queue[last_index]['data'] = serialize_for_event(instance)
100+
queue[last_index]['snapshots']['postchange'] = get_snapshots(instance, action)['postchange']
96101
else:
97102
enqueue_object(queue, instance, request.user, request.id, action)
98103
events_queue.set(queue)

0 commit comments

Comments
 (0)