[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
|
lockedToMaster bool
|
||||||
context context.Context
|
context context.Context
|
||||||
license *model.License
|
license *model.License
|
||||||
licenseMutex sync.Mutex
|
licenseMutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type TraceOnAdapter struct{}
|
type TraceOnAdapter struct{}
|
||||||
@@ -330,7 +330,10 @@ func (ss *SqlSupplier) GetMaster() *gorp.DbMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) GetSearchReplica() *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()
|
return ss.GetMaster()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +346,10 @@ func (ss *SqlSupplier) GetSearchReplica() *gorp.DbMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) GetReplica() *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()
|
return ss.GetMaster()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,36 @@ import (
|
|||||||
"github.com/mattermost/mattermost-server/v5/store/storetest"
|
"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) {
|
func TestGetReplica(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user