Skip to content

Commit b5cb67b

Browse files
committed
Fixes: #15194 - Check the whole queue for matching queued webhooks
1 parent 0bfb977 commit b5cb67b

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

netbox/extras/signals.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,21 @@ def run_validators(instance, validators):
5555
clear_events = Signal()
5656

5757

58-
def is_same_object(instance, webhook_data, request_id):
58+
def last_matching_index(instance, queue, request_id):
5959
"""
60-
Compare the given instance to the most recent queued webhook object, returning True
61-
if they match. This check is used to avoid creating duplicate webhook entries.
60+
Find the latest queued webhook object matching the given instance, returning its index.
61+
If no object is found, return None. This check is used to avoid creating duplicate webhook
62+
entries.
6263
"""
63-
return (
64-
ContentType.objects.get_for_model(instance) == webhook_data['content_type'] and
65-
instance.pk == webhook_data['object_id'] and
66-
request_id == webhook_data['request_id']
67-
)
64+
try:
65+
return max(
66+
index_ for index_, webhook_data in enumerate(queue)
67+
if ContentType.objects.get_for_model(instance) == webhook_data['content_type'] and
68+
instance.pk == webhook_data['object_id'] and
69+
request_id == webhook_data['request_id']
70+
)
71+
except ValueError:
72+
return None
6873

6974

7075
@receiver((post_save, m2m_changed))
@@ -112,12 +117,12 @@ def handle_changed_object(sender, instance, **kwargs):
112117
objectchange.request_id = request.id
113118
objectchange.save()
114119

115-
# If this is an M2M change, update the previously queued webhook (from post_save)
120+
# Update the previously queued webhook from a preceeding post_save
116121
queue = events_queue.get()
117-
if m2m_changed and queue and is_same_object(instance, queue[-1], request.id):
122+
if queue and (last_index := last_matching_index(instance, queue, request.id)) is not None:
118123
instance.refresh_from_db() # Ensure that we're working with fresh M2M assignments
119-
queue[-1]['data'] = serialize_for_event(instance)
120-
queue[-1]['snapshots']['postchange'] = get_snapshots(instance, action)['postchange']
124+
queue[last_index]['data'] = serialize_for_event(instance)
125+
queue[last_index]['snapshots']['postchange'] = get_snapshots(instance, action)['postchange']
121126
else:
122127
enqueue_object(queue, instance, request.user, request.id, action)
123128
events_queue.set(queue)

0 commit comments

Comments
 (0)