Repository navigation
agent/local: serialize full and partial state syncs to fix stale TTL checks - #24069
Open
akasakariko wants to merge 2 commits into
Open
akasakariko wants to merge 2 commits into
akasakariko wants to merge 2 commits into
Conversation
|
Thank you for your submission! We require that all contributors sign our Contributor License Agreement ("CLA") before we can accept the contribution. Read and sign the agreement Learn more about why HashiCorp requires a CLA and what the CLA includes Have you signed the CLA already but the status is still pending? Recheck it. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #24064
When a full anti-entropy sync (
updateSyncState) overlaps a partial sync (SyncChanges), a catalog check can remaincriticaluntil a later full sync while local state ispassing:passingHealth.NodeCheckssnapshot before acquiring the state lock for reconciliationcritical(TTL expired) and a concurrent partialSyncChangespushescriticalto the catalog and marks itInSyncpassing(dirty)passingHealth.NodeCheckssnapshot and marks the localpassingcheckInSync, so the catalog check remainscriticaluntil a later full syncpassingheartbeats do not dirty the check, so partial syncs do not repair the mismatchThis 11-line production change adds
syncLock sync.MutextoStateand acquires it withdeferrelease inupdateSyncStateandSyncChangesbefore the state lock, serializing full-sync reads and reconciliation against partial writes while letting localUpdateCheckcalls proceed during catalog reads; there are no public API, dependency, or configuration changesTesting & Reproduction steps
TestState_SyncFull_ConcurrentCheckUpdateuses an optionalfakeRPChandler to holdHealth.NodeChecksduring a full sync and reproduce the interleaving aboveAll validation ran locally on Go 1.26.9 (
darwin/arm64):go test ./agent/local -run '^TestState_SyncFull_ConcurrentCheckUpdate$' -count=10— failed 10/10-race, and affected package suites all PASS):Additional validation:
./agenttests forupdateTTLCheck,UpdateCheck,UpdateCheck_ACLDeny, andAddServices_AliasUpdateCheckNotRevertedpassed (without-race)go vet,golangci-lint2.11.4 (0 issues),gofmt,git diff --check, native binary build, andlinux/amd64affected-package cross-build passedTestAgentAntiEntropy_Check_DeferSynctiming assertion while-racecompilation ran concurrently (root cause unconfirmed); 10 isolated runs on fixed code and 10 on baseline passed, and subsequent full affected suites passed normally and with-race./agentsuite, and GitHub CI were not runLinks
PR Checklist
PCI review checklist