fix(memorystore): prevent infinite reconciliation drift loop by aligning connections list length - #11547
Conversation
0a6c617 to
4306a49
Compare
| desired.CrossInstanceReplicationConfig = maskedActual.CrossInstanceReplicationConfig | ||
| } | ||
|
|
||
| // Align connections list length to prevent false drift detection on server-generated connections |
There was a problem hiding this comment.
Not a blocker of this PR.
This seems another use case for the issue I've experienced: The API converts the desired state into a value that we cannot easily simulate on our end, unlike predictable conversions we already handle(e.g., mapping project ID to number or altering string/enum casing, ordering, etc).
I am leaning toward a more generic solution that deserves a design discussion: storing a hash(last applied desired state, last applied actual state) in new field "ObservedState.LastApplied". We can then compare the current hash(desired state, actual state) against this stored hash to detect diffs. We should document the specific fields requiring this logic so we don't hash all fields unnecessarily.
There was a problem hiding this comment.
Yeah this makes sense, a nice thing in this case is that we do store the received values in status so we shouldn't lose this data
There was a problem hiding this comment.
I think this is a different use case? The reason we want observedState to store the actual value for comparison is that the service-returned value and the user-provided value are different. And for this use case, the service still return the same values.
There was a problem hiding this comment.
Agreed. The current logic to ensure desired is a subset of actual works to me.
edbbffd to
b452612
Compare
422f3dc to
c73c750
Compare
2faf101 to
c559701
Compare
…s with injective subset connection matching
…lign with CRD fields
d3d1581 to
05043ad
Compare
05043ad to
19f49f4
Compare
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: acpana, maqiuyujoyce 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 |
a634d60
Why is this change necessary?
During E2E testing of network connectivity topologies, we observed that
MemorystoreInstancecontrollers can fall into an infinite reconciliation loop due to false drift detection on theendpoints[i].connectionslist.Specifically:
desired), a user defines the target VPC network(s) underspec.endpoints[i].connections(typically 1 connection item representing the intended PSC network target).actualconnections list that is longer than the user'sdesiredlist,tags.DiffForTopLevelFieldsflags the length mismatch as a drift. KCC repeatedly sends update requests attempting to shrink the connections list, which GCP ignores, resulting in an infinite reconciliation loop.What does this change do?
Connectionslist length before diffing (pkg/controller/direct/memorystore/memorystoreinstance_controller.go):Truncates the server-generated extra
ConnectionsinmaskedActualto matchlen(desiredEndpoint.Connections)before comparison (actualEndpoint.Connections = actualEndpoint.Connections[:len(desiredEndpoint.Connections)]).maskedActualcopy used for drift comparison against the user'sspec. It does not discard any user-configured target connections, nor does it affect the full observed state reported instatus.endpoints. It ensures we compare exactly the user-declared intent (desired) against the corresponding actual connection items without failing on extra server-created replica entries.pkg/controller/direct/directbase/operations.go):Updates
directbase/operations.goto prevent partial status updates from overwriting existing status fields (such asconditionsorexternalRef) withnil.Aligns/sorts HTTP log entries for the
MemorystoreInstancetest fixtures to prevent test flakiness.