✨ Deduplicate events before sending them into the workqueue.#1390
Conversation
This avoids race conditions where extra reconciles can happen rarely.
|
Replaces #1380 but covers all three handler types instead. |
|
If we got with this approach, should probably rewrite this to use k8s.io/apimachinery/pkg/util/sets. |
Also make sure that enqueue_mapped preserves order.
Should be good on ordering. Still leaving owners as unordered since the underlying order is meaningless and can be shuffled. |
| // Delete implements EventHandler | ||
| func (e *EnqueueRequestForOwner) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { | ||
| for _, req := range e.getOwnerReconcileRequest(evt.Object) { | ||
| reqs := map[reconcile.Request]empty{} |
There was a problem hiding this comment.
Is this needed here and in Generic? I would have assumed that kube doesn't allow multiple identical ownerRefs
There was a problem hiding this comment.
Hmm, I don't actually know what happens if you try to give the same non-controller owner twice.
There was a problem hiding this comment.
I bet you could have duplicates, +patchMergeKey=uid so it will theoretically dedup on UID but you could have invalid owner refs with the wrong UID and duplicate names? I would also be 100% fine with not handling that cleanly and risking spurious reconciles since that should be very hard to make happen.
There was a problem hiding this comment.
Yeah I would prefer to omit that here and in Generic
There was a problem hiding this comment.
If not in Delete nor Generic, why have it in Create?
There was a problem hiding this comment.
Looking at the code again, I think we should probably just leave it. It would complicate the flow to only do it sometimes, would have to switch back to returning a slice and then process it again, the extra memory allocations and code complexity seems not worth it.
|
🦆 I tried to wrap my head around if/why we should dedupe in the single-object events (Create, Delete, Generic). It seems to me that if we do it in the Update event, we should do it in all events, right? 🦆 Should a user expect 🦆 Perhaps 🦆 If ❓ If 🤔 after all that... I think we should dedupe as little or as much as we like. Any amount is an improvement and approaches the ideal, where it happens directly in Perhaps we should change the documentation on any/all of these Handlers now to allow deduplication to change over time. |
Update events contain two objects, old obj and new obj which is why there is a good chance this might happen. Adding de-duplication for anything else is essentially assuming that users provide buggy mappers. I am apposed to that.
No, see above.
I am opposed to that. What this change is doing in the first place is a performance optimization that for most controllers shouldn't matter. I am strictly opposed to complicating our API and dev user experience even the slightest for this. Adding a redundant way to do the same thing would fall into the "complicating API" category.
It won't, they rejected the upstream PR. |
|
@alvaroaleman I think this should be all set now? |
alvaroaleman
left a comment
There was a problem hiding this comment.
/label tide/merge-method-squash
/lgtm
/approve
Sorry, I didn't have time initially and then it fell off my radar 🙃
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: alvaroaleman, coderanger The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/retest |
1 similar comment
|
/retest |
Update tests for controller-runtime changes from 0.8.2 to 0.9.2(+). Most of these changes react to kubernetes-sigs/controller-runtime#1399, which made the fake client's Delete behave more like the real thing: - If the object has finalizers, set `DeletionTimestamp` but don't actually delete. - If there are no finalizers, actually delete. - Updates that remove the last finalizer from an object with a `DeletionTimestamp` actually delete the object. Then there's kubernetes-sigs/controller-runtime#1390 which deduplicates objects in the reconcile queue for Update actions.
…tes-sigs#1390) * ✨ Deduplicate events before sending them into the workqueue. This avoids race conditions where extra reconciles can happen rarely. * ✨ Switch to map[string]struct{} to reduce memory usage slightly. Also make sure that enqueue_mapped preserves order. * 📝 Update function doc for getOwnerReconcileRequest. * 🎨 Fix up duplication tests and ensure Update for _mapped dedups between both objects.
This avoids race conditions where extra reconciles can happen rarely.
I still think kubernetes/kubernetes#99185 is a better solution but failing that, here is a "userspace" solution.