[MM-28397] Fix data race in SqlSupplier (#15419)
* Fix data race in SqlSupplier * Add comment Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
96a3407b7a
Коммит
4e1824e143
@@ -115,7 +115,7 @@ type SqlSupplier struct {
|
||||
lockedToMaster bool
|
||||
context context.Context
|
||||
license *model.License
|
||||
licenseMutex sync.Mutex
|
||||
licenseMutex sync.RWMutex
|
||||
}
|
||||
|
||||
type TraceOnAdapter struct{}
|
||||
@@ -330,7 +330,10 @@ func (ss *SqlSupplier) GetMaster() *gorp.DbMap {
|
||||
}
|
||||
|
||||
func (ss *SqlSupplier) GetSearchReplica() *gorp.DbMap {
|
||||
if ss.license == nil {
|
||||
ss.licenseMutex.RLock()
|
||||
license := ss.license
|
||||
ss.licenseMutex.RUnlock()
|
||||
if license == nil {
|
||||
return ss.GetMaster()
|
||||
}
|
||||
|
||||
@@ -343,7 +346,10 @@ func (ss *SqlSupplier) GetSearchReplica() *gorp.DbMap {
|
||||
}
|
||||
|
||||
func (ss *SqlSupplier) GetReplica() *gorp.DbMap {
|
||||
if len(ss.settings.DataSourceReplicas) == 0 || ss.lockedToMaster || ss.license == nil {
|
||||
ss.licenseMutex.RLock()
|
||||
license := ss.license
|
||||
ss.licenseMutex.RUnlock()
|
||||
if len(ss.settings.DataSourceReplicas) == 0 || ss.lockedToMaster || license == nil {
|
||||
return ss.GetMaster()
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,36 @@ import (
|
||||
"github.com/mattermost/mattermost-server/v5/store/storetest"
|
||||
)
|
||||
|
||||
// This test was used to consistently reproduce the race
|
||||
// before the fix in MM-28397.
|
||||
// Keeping it here to help avoiding future regressions.
|
||||
func TestSupplierLicenseRace(t *testing.T) {
|
||||
settings := makeSqlSettings(model.DATABASE_DRIVER_SQLITE)
|
||||
settings.DataSourceReplicas = []string{":memory:"}
|
||||
settings.DataSourceSearchReplicas = []string{":memory:"}
|
||||
supplier := sqlstore.NewSqlSupplier(*settings, nil)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(3)
|
||||
|
||||
go func() {
|
||||
supplier.UpdateLicense(&model.License{})
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
supplier.GetReplica()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
supplier.GetSearchReplica()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestGetReplica(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
|
||||
Ссылка в новой задаче
Block a user