[PR #14131] [MERGED] Fixes #14081: Fix cached counters on delete for parent-child items #14318

Closed
opened 2025-12-29 23:23:47 +01:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbox-community/netbox/pull/14131
Author: @arthanson
Created: 10/27/2023
Status: Merged
Merged: 12/12/2023
Merged by: @jeremystretch

Base: developHead: 14081-cached-counters


📝 Commits (2)

  • acfde34 14081 fixed cached counters on delete for parent-child items
  • 525ee40 Misc cleanup

📊 Changes

1 file changed (+15 additions, -5 deletions)

View changed files

📝 netbox/utilities/counters.py (+15 -5)

📄 Description

Fixes: #14081

@jeremystretch this will cause one extra db call on delete to an object tracked for a cached counter. The other option would be to save/check the objects to a request-specific queue (like webhooks uses) this code would be less clear but would obviate the need for another DB call. As it is just on delete, not sure if the extra DB call is a problem here?

The root issue is when you have a parent-child relationship (like inventory items) using MPTT and you do bulk-delete on them you wind up getting three delete signals instead of two:

1 for the child object being deleted from the cascade delete of the parent
1 for the parent object
1 additional one for the child object (not cascade deleted)

As can be seen from below, all the params to post_delete are the same except for the instance and origin not matching for the child delete case, but this is needed if you aren't doing bulk_delete and just delete the parent item:

sender: <class 'dcim.models.device_components.InventoryItem'> instance: invc1 instance_pk: 40 origin: inv1 parent_pk: 88, parent_model: <class 'dcim.models.devices.Device'> kwargs: {'signal': <django.db.models.signals.ModelSignal object at 0x101ad9510>, 'using': 'default'}
sender: <class 'dcim.models.device_components.InventoryItem'> instance: inv1 instance_pk: 39 origin: inv1 parent_pk: 88, parent_model: <class 'dcim.models.devices.Device'> kwargs: {'signal': <django.db.models.signals.ModelSignal object at 0x101ad9510>, 'using': 'default'}
sender: <class 'dcim.models.device_components.InventoryItem'> instance: invc1 instance_pk: 40 origin: invc1 parent_pk: 88, parent_model: <class 'dcim.models.devices.Device'> kwargs: {'signal': <django.db.models.signals.ModelSignal object at 0x101ad9510>, 'using': 'default'}

Because of the way MPTT is doing the delete the instance between the calls is actually two different instances, so I tried directly setting _previously_deleted inside post_delete on the instance, but it isn't there on the second call.

This causes an additional DB call when deleting a cached_counted item. The other way I thought of potentially handling this was to store the deleted ids in a request queue (like webhooks code uses) and check if it is in the queue (already deleted) before decrementing the counter. The queue would need to be cleared at the end of the request. However this makes the code less-clear and splits the queue init and handling.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbox-community/netbox/pull/14131 **Author:** [@arthanson](https://github.com/arthanson) **Created:** 10/27/2023 **Status:** ✅ Merged **Merged:** 12/12/2023 **Merged by:** [@jeremystretch](https://github.com/jeremystretch) **Base:** `develop` ← **Head:** `14081-cached-counters` --- ### 📝 Commits (2) - [`acfde34`](https://github.com/netbox-community/netbox/commit/acfde343c2fd7ad707004458eb3d22fc08e41803) 14081 fixed cached counters on delete for parent-child items - [`525ee40`](https://github.com/netbox-community/netbox/commit/525ee4055ba3670a6fc9040a1dea797ed590c826) Misc cleanup ### 📊 Changes **1 file changed** (+15 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `netbox/utilities/counters.py` (+15 -5) </details> ### 📄 Description ### Fixes: #14081 @jeremystretch this will cause one extra db call on delete to an object tracked for a cached counter. The other option would be to save/check the objects to a request-specific queue (like webhooks uses) this code would be less clear but would obviate the need for another DB call. As it is just on delete, not sure if the extra DB call is a problem here? The root issue is when you have a parent-child relationship (like inventory items) using MPTT and you do bulk-delete on them you wind up getting three delete signals instead of two: 1 for the child object being deleted from the cascade delete of the parent 1 for the parent object 1 additional one for the child object (not cascade deleted) As can be seen from below, all the params to post_delete are the same except for the instance and origin not matching for the child delete case, but this is needed if you aren't doing bulk_delete and just delete the parent item: ``` sender: <class 'dcim.models.device_components.InventoryItem'> instance: invc1 instance_pk: 40 origin: inv1 parent_pk: 88, parent_model: <class 'dcim.models.devices.Device'> kwargs: {'signal': <django.db.models.signals.ModelSignal object at 0x101ad9510>, 'using': 'default'} sender: <class 'dcim.models.device_components.InventoryItem'> instance: inv1 instance_pk: 39 origin: inv1 parent_pk: 88, parent_model: <class 'dcim.models.devices.Device'> kwargs: {'signal': <django.db.models.signals.ModelSignal object at 0x101ad9510>, 'using': 'default'} sender: <class 'dcim.models.device_components.InventoryItem'> instance: invc1 instance_pk: 40 origin: invc1 parent_pk: 88, parent_model: <class 'dcim.models.devices.Device'> kwargs: {'signal': <django.db.models.signals.ModelSignal object at 0x101ad9510>, 'using': 'default'} ``` Because of the way MPTT is doing the delete the instance between the calls is actually two different instances, so I tried directly setting _previously_deleted inside post_delete on the instance, but it isn't there on the second call. This causes an additional DB call when deleting a cached_counted item. The other way I thought of potentially handling this was to store the deleted ids in a request queue (like webhooks code uses) and check if it is in the queue (already deleted) before decrementing the counter. The queue would need to be cleared at the end of the request. However this makes the code less-clear and splits the queue init and handling. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2025-12-29 23:23:47 +01:00
adam closed this issue 2025-12-29 23:23:48 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#14318