-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #15194: Prevent enqueuing duplicate events for an object #16366
Conversation
Hi @jeremystretch, thank you very much for this PR! Looks very promising so far, though I still seem to have one issue. I'm just in the process of writing a couple of tests for NetBox DNS, and I found something I couldn't track down yet. This test def test_update_zone_add_nameservers(self):
zone = Zone.objects.create(name="zone1.example.com", **self.zone_data)
zone.snapshot()
url = reverse("plugins:netbox_dns:zone_edit", kwargs={"pk": zone.pk})
request = RequestFactory().get(url)
request.id = uuid.uuid4()
request.user = self.user
self.assertEqual(self.queue.count, 0, msg="Unexpected jobs found in queue")
with event_tracking(request):
zone.nameservers.add(self.nameservers[1])
zone.nameservers.add(self.nameservers[2])
zone.save()
self.assertEqual(self.queue.count, 1)
job = self.queue.jobs[0]
print(job.kwargs['snapshots'])
self.assertEqual(len(job.kwargs['data']['nameservers']), 2)
self.assertIsNotNone(job.kwargs['snapshots'].get('prechange'))
self.assertIsNotNone(job.kwargs['snapshots'].get('postchange'))
self.assertEqual(len(job.kwargs['snapshots']['prechange']['nameservers']), 0)
self.assertEqual(len(job.kwargs['snapshots']['postchange']['nameservers']), 2) fails with the check that the prechange snapshot is If I insert an additional with event_tracking(request):
zone.save()
zone.nameservers.add(self.nameservers[1])
zone.nameservers.add(self.nameservers[2])
zone.save() As I said, I haven't thoroughly investigated this, but it seems there is still something missing somewhere (might well be on my side). |
For reference: def test_update_zone(self):
zone = Zone.objects.create(name="zone1.example.com", **self.zone_data)
zone.snapshot()
url = reverse("plugins:netbox_dns:zone_edit", kwargs={"pk": zone.pk})
request = RequestFactory().get(url)
request.id = uuid.uuid4()
request.user = self.user
self.assertEqual(self.queue.count, 0, msg="Unexpected jobs found in queue")
with event_tracking(request):
zone.soa_refresh = 86400
zone.save()
self.assertEqual(self.queue.count, 1)
job = self.queue.jobs[0]
self.assertEqual(job.kwargs['data']['soa_refresh'], 86400)
self.assertIsNotNone(job.kwargs['snapshots'].get('prechange'))
self.assertIsNotNone(job.kwargs['snapshots'].get('postchange'))
self.assertEqual(job.kwargs['snapshots']['prechange']['soa_refresh'], Zone.get_defaults()['soa_refresh'])
self.assertEqual(job.kwargs['snapshots']['postchange']['soa_refresh'], 86400) This test succeeds, so it's definitely linked to M2M updates somehow. |
Two additional things:
def test_update_zone_remove_nameservers(self):
zone = Zone.objects.create(name="zone1.example.com", **self.zone_data)
zone.nameservers.set(self.nameservers[1:])
zone.snapshot()
url = reverse("plugins:netbox_dns:zone_edit", kwargs={"pk": zone.pk})
request = RequestFactory().get(url)
request.id = uuid.uuid4()
request.user = self.user
self.assertEqual(self.queue.count, 0, msg="Unexpected jobs found in queue")
with event_tracking(request):
zone.nameservers.set([])
zone.save()
self.assertEqual(self.queue.count, 1)
job = self.queue.jobs[0]
self.assertEqual(len(job.kwargs['data']['nameservers']),0 )
self.assertIsNotNone(job.kwargs['snapshots'].get('prechange'))
self.assertIsNotNone(job.kwargs['snapshots'].get('postchange'))
self.assertEqual(len(job.kwargs['snapshots']['prechange']['nameservers']), 2)
self.assertEqual(len(job.kwargs['snapshots']['postchange']['nameservers']), 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jeremystretch, apart from the problem I found and described in the comments this works absolutely great for me. I ran a couple of tests with the webhook_receiver
and there the issue with the M2M updates losing the pre-change snapshot does not occur.
So this PR fixes the issue for me. If I can find what causes the issue with my tests and it's actually a problem with NetBox I will open a new issue. For now I'm perfectly fine with it - thank you very much for fixing this so elegantly and showing me a much better way of testing event queue-related stuff than I devised. That's really awesome.
Update to the test issue: That only seems to happen in the |
@peteeckel I think the issue with your test is that the |
Fixes: #15194
events_queue
context variable from a list to a dictionary, to enable identifying each object by a unique key.enqueue_object()
to designate a unique key for each object in the events queue, instead of comparing each new object to the previous entry.is_same_object()
function.A huge thank you to @peteeckel for his thorough research into this issue and his initial work on a solution under PR #15318!