fix(snapshot): replace unsafe.Pointer CAS with atomic.Pointer[error] - #75
Merged
Merged
Conversation
RestoreSnapshot recorded the first parallel-deletion error with a raw unsafe.Pointer and atomic.CompareAndSwapPointer. atomic.Pointer[error] provides the same lock-free compare-and-swap with static type safety, removing the unsafe import from the package entirely. Behaviour is unchanged: the first goroutine to fail still wins the CAS, later errors are still discarded, and a non-nil result still short-circuits the restore before the copy phase. Adds TestRestoreSnapshot_returnsRemovalError, which covers that error path (previously untested) and passes against both the old and new implementations. Updates the CONTRIBUTING.md concurrency section, which documented the unsafe.Pointer snippet. Closes kavix#68 Signed-off-by: charlie-morrison <charliemorrison2228@gmail.com>
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.
Closes #68.
RestoreSnapshotrecorded the first parallel-deletion error with a rawunsafe.Pointer+atomic.CompareAndSwapPointer. This swaps it foratomic.Pointer[error], which is the same lock-free compare-and-swap with static type safety — theunsafeimport is gone from the package.On the two options in the issue.
errgroupwould work, but it means addinggolang.org/x/syncto ago.modthat currently has two direct dependencies, and a plainsync.Mutexdrops the lock-free property the design doc calls out by name.atomic.Pointer[error]is stdlib, needs no new dependency, and keeps the existing CAS semantics exactly — so it seemed like the closest thing to a strict improvement of what was already there. Happy to switch toerrgroupor a mutex if you'd rather have it exactly as filed; it's a small change either way.Behaviour is unchanged — same first-error-wins CAS, same discard of later errors, same short-circuit before the copy phase.
Verification. That error path had no test coverage (every existing
RestoreSnapshottest is happy-path), so "no behaviour change" wasn't checkable. This addsTestRestoreSnapshot_returnsRemovalError, which makes a top-level entry un-removable and asserts both that the error surfaces and that phase 2 never ran. I ran it against the originalunsafeimplementation first, where it also passes — so it's pinning existing behaviour, not describing the new code. It skips underroot(uid 0 ignores the directory permissions it relies on) and restores the mode int.Cleanupsot.TempDircan clean up.go build ./...,go vet ./...,gofmt -l— cleango test -race -count=1 ./...— all packages passAlso updated the Parallel Deletion (Lock-Free CAS) section of
CONTRIBUTING.md— it documented theunsafe.Pointersnippet directly, so it would have gone stale on merge.No behaviour, API, or dependency changes.