-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make sure only one package syncing operation happens at a time #120
Conversation
Codecov Report
@@ Coverage Diff @@
## main #120 +/- ##
==========================================
+ Coverage 74.89% 75.25% +0.36%
==========================================
Files 22 22
Lines 1629 1637 +8
==========================================
+ Hits 1220 1232 +12
+ Misses 307 304 -3
+ Partials 102 101 -1
Continue to review full report at Codecov.
|
Hi @tigrannajaryan , one case which could lead to race is when a package having same name, version and hash as previous package is tried to be Installed. Ideally the packagesyncer should ignore the request but due to race condition it could try to install it again. Do you have any other cases on top of your mind? |
I think the most common case we want to test for is this:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far. Let's add a test and should be good to merge
@@ -54,6 +54,9 @@ type ClientCommon struct { | |||
|
|||
// Indicates that the Client is fully stopped. | |||
stoppedSignal chan struct{} | |||
|
|||
// Mutex for Package Syncing | |||
PackageSyncComplete sync.Mutex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: we use "Mutex" prefix elsewhere in this codebase.
PackageSyncComplete sync.Mutex | |
PackageSyncMutex sync.Mutex |
Facing the following race condition. Trying to debug it. Any help would be appreciated.
|
@kpratyus are you still interested in continuing this work? |
Closing since there hasn't been updates to the PR for a while. Please reopen if still active. |
Signed-off-by: Paschalis Tsilias <paschalis.tsilias@grafana.com>
Signed-off-by: Paschalis Tsilias <paschalis.tsilias@grafana.com>
This PR revives work done in previous PRs (#118, #120) to make sure that only a single package syncing operation is ever in flight and also adds a test. The previous PRs did not account for needing to also protect `initStatuses` and `SetPackageStatuses`, so that's why the Lock and Unlock statements are not just paired in doSync. If you think the intent would be clearer using a sync.WaitGroup, let me know. The new test makes sure that the mutex correctly protects the local storage; if we comment out the calls to Lock/Unlock and run the test with the `-race` flag we can see the race condition taking place <details> ``` # Without using the mutex we can see the race condition of messages sent in parallel $ go test -run=TestPackageUpdatesInParallel -v -race -count=1 === RUN TestPackageUpdatesInParallel ================== WARNING: DATA RACE Write at 0x00c00003cdb0 by goroutine 10: github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).SetLastReportedStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:95 +0x34 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).reportStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:335 +0x78 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).syncPackage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:199 +0x4dc github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:132 +0x3b0 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Previous read at 0x00c00003cdb0 by goroutine 8: github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).LastReportedStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:91 +0x30 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).initStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:88 +0x64 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:59 +0x78 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func2() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:197 +0x4d0 Goroutine 10 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func3() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:216 +0x4d0 Goroutine 8 (finished) created at: github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:196 +0x4b0 testing.tRunner() /opt/homebrew/Cellar/go/1.22.2/libexec/src/testing/testing.go:1689 +0x180 testing.(*T).Run.gowrap1() /opt/homebrew/Cellar/go/1.22.2/libexec/src/testing/testing.go:1742 +0x40 ================== ================== WARNING: DATA RACE Write at 0x00c0000999e0 by goroutine 11: runtime.mapaccess2_faststr() /opt/homebrew/Cellar/go/1.22.2/libexec/src/runtime/map_faststr.go:108 +0x42c github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).CreatePackage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:50 +0x74 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).syncPackage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:203 +0x528 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:132 +0x3b0 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Previous read at 0x00c0000999e0 by goroutine 10: runtime.mapdelete() /opt/homebrew/Cellar/go/1.22.2/libexec/src/runtime/map.go:696 +0x43c github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).Packages() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:36 +0x64 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).deleteUnneededLocalPackages() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:303 +0x58 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:125 +0x1b4 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Goroutine 11 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func2() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:197 +0x4d0 Goroutine 10 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func3() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:216 +0x4d0 ================== ================== WARNING: DATA RACE Write at 0x00c00003cdb0 by goroutine 11: github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).SetLastReportedStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:95 +0x34 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).reportStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:335 +0x78 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).syncPackage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:229 +0x780 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:132 +0x3b0 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Previous write at 0x00c00003cdb0 by goroutine 10: github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).SetLastReportedStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:95 +0x34 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).reportStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:335 +0x78 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).syncPackage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:229 +0x780 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:132 +0x3b0 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Goroutine 11 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func2() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:197 +0x4d0 Goroutine 10 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func3() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:216 +0x4d0 ================== ================== WARNING: DATA RACE Write at 0x00c00003cdb0 by goroutine 10: github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).SetLastReportedStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:95 +0x34 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).reportStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:335 +0x78 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:151 +0x69c github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Previous write at 0x00c00003cdb0 by goroutine 11: github.com/open-telemetry/opamp-go/client/internal.(*InMemPackagesStore).SetLastReportedStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/inmempackagestore.go:95 +0x34 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).reportStatuses() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:335 +0x78 github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).doSync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:151 +0x69c github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync.gowrap1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x4c Goroutine 10 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func3() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:216 +0x4d0 Goroutine 11 (running) created at: github.com/open-telemetry/opamp-go/client/internal.(*packagesSyncer).Sync() /Users/tpaschalis/GitRepos/opamp-go/client/internal/packagessyncer.go:69 +0x15c github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func1() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:185 +0x68 github.com/open-telemetry/opamp-go/client/types.CallbacksStruct.OnMessage() /Users/tpaschalis/GitRepos/opamp-go/client/types/callbacks.go:161 +0x84 github.com/open-telemetry/opamp-go/client/types.(*CallbacksStruct).OnMessage() <autogenerated>:1 +0x20 github.com/open-telemetry/opamp-go/client/internal.(*receivedProcessor).ProcessReceivedMessage() /Users/tpaschalis/GitRepos/opamp-go/client/internal/receivedprocessor.go:160 +0xe94 github.com/open-telemetry/opamp-go/client/internal.TestPackageUpdatesInParallel.func2() /Users/tpaschalis/GitRepos/opamp-go/client/internal/httpsender_test.go:197 +0x4d0 ================== testing.go:1398: race detected during execution of test --- FAIL: TestPackageUpdatesInParallel (0.10s) FAIL exit status 1 FAIL github.com/open-telemetry/opamp-go/client/internal 0.286s ``` </details> Fixes #84
This is the revised PR for issue #84 . As proposed I am in the process to write a test case for testing the changes (It will take some time as I am new to the codebase).