xds: suppress the duplicate errors at the client side#9185
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #9185 +/- ##
==========================================
- Coverage 83.23% 83.22% -0.02%
==========================================
Files 420 420
Lines 34024 34035 +11
==========================================
+ Hits 28321 28325 +4
+ Misses 4275 4274 -1
- Partials 1428 1436 +8
🚀 New features to boost your workflow:
|
| isDuplicateErr := state.md.ErrState != nil && state.md.ErrState.Err != nil && state.md.ErrState.Err.Error() == uErr.Err.Error() | ||
| var errState *xdsresource.UpdateErrorMetadata | ||
| if md.ErrState != nil { | ||
| errState = &xdsresource.UpdateErrorMetadata{ |
There was a problem hiding this comment.
Why do we need to do this ? Can't we directly do state.md.ErrState = md.ErrState like earlier ?
There was a problem hiding this comment.
md.ErrState contains concatenated errors for all resources in the received update, so it's impossible to detect an error duplication right, if there was more than one error. It might be worth it to keep uErr.Err (which is a resource specific error) as a separate member in the state to avoid confusion? WDYT?
There was a problem hiding this comment.
I dont think that is the right way to go. We should not change the error stored. We can instead compare the error in state with the ms error like :
isDuplicateErr := state.md.ErrState != nil && state.md.ErrState.Err != nil && state.md.ErrState.Err.Error() == md.ErrState.Err.Error()
WDYT ?
There was a problem hiding this comment.
We cannot compare state.md.ErrState.Err.Error() == md.ErrState.Err.Error() in order to detect a duplication, e.g. Let's assume that we got an update for three resources, where two of them got errors:
Resource A(Ok)Resource B(Error B)Resource C(Error C)
md.ErrState.Err.Error() returns a concatenated error "Error B; Error C". This concatenated error is stored in state.md.ErrState.
Then the next update brings a duplicate error for the Resource C only, because Resource B is fine, we did not get an update for that resource or the error is different:
Resource A(Ok)Resource B(Ok)Resource C(Error C)
md.ErrState.Err.Error() returns a concatenated error "Error C", which is different from the previously stored one "Error B; Error C". Even though the duplication is there a simple comparison will not work.
As an alternative I can try to check if the concatenated error in the md.ErrState contains a resource specific error to seek for a duplication.
There was a problem hiding this comment.
I have changed the logic to look for a duplicate resource error in the concatenated error (md.ErrState)
| }) | ||
| } | ||
| state.md.ErrState = md.ErrState | ||
| isDuplicateErr := state.md.ErrState != nil && state.md.ErrState.Err != nil && state.md.ErrState.Err.Error() == uErr.Err.Error() |
There was a problem hiding this comment.
Also instead of evaluating this as a variable and then checking can we instead do the assignment first(which I assume needs to be done for either case) and then directly in an if block we can evaluate the condition and call continue on true. WDYT ?
There was a problem hiding this comment.
state works as an cache of the previously received error for the resource, so trying to find out if there was an error duplication after updating state would always return true
There was a problem hiding this comment.
Right! but we can do the check first and if true call continue, because if we are getting the same error, we might not need to update the state? Or can the status be different ?
There was a problem hiding this comment.
The stored metadata ErrState may differ, this is why we need to update it even if a duplicate error for a resource is detected. This is also the reason why the duplicate check has to be done before updating it. Please, look at the comment with an example that I made: #9185 (comment)
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces duplicate error suppression for ADS resource updates in the xDS client, skipping watcher notifications when duplicate errors are received, and adds a corresponding test to verify this behavior. The reviewer identified a critical issue in authority.go where a nil pointer dereference panic could occur if md.ErrState is nil but uErr.Err is non-nil, and provided a code suggestion to safely initialize errState.
| // duplicate error notification to the watcher. | ||
| // | ||
| // Note: This behavior (suppress duplicate error notifications to watchers) was | ||
| // originally introduced to handle invalid EDS resources (missing localities) as |
There was a problem hiding this comment.
I don't think we need this note here.
| } | ||
| if req.GetErrorDetail() != nil { | ||
| if count := nackCount.Add(1); count >= 3 { | ||
| nackReceivedCh.Send(nil) |
There was a problem hiding this comment.
nit: Can we change the nackReceivedCh to be a go channel and close it here since it is only sent to once. We do not need a size one channel.
| isDuplicateErr := state.md.ErrState != nil && state.md.ErrState.Err != nil && state.md.ErrState.Err.Error() == uErr.Err.Error() | ||
| var errState *xdsresource.UpdateErrorMetadata | ||
| if md.ErrState != nil { | ||
| errState = &xdsresource.UpdateErrorMetadata{ |
There was a problem hiding this comment.
I dont think that is the right way to go. We should not change the error stored. We can instead compare the error in state with the ms error like :
isDuplicateErr := state.md.ErrState != nil && state.md.ErrState.Err != nil && state.md.ErrState.Err.Error() == md.ErrState.Err.Error()
WDYT ?
| }) | ||
| } | ||
| state.md.ErrState = md.ErrState | ||
| isDuplicateErr := state.md.ErrState != nil && state.md.ErrState.Err != nil && state.md.ErrState.Err.Error() == uErr.Err.Error() |
There was a problem hiding this comment.
Right! but we can do the check first and if true call continue, because if we are getting the same error, we might not need to update the state? Or can the status be different ?
Fixes #8994
This change suppresses duplicate errors on the xds client side by skipping calling watchers for the duplicates. This also prevents generating new child names for the same broken EDS resource (EDS resource has no localities) that is being re-send by the control plane.
RELEASE NOTES: