fix: make data syncer run configurable on mode (2->3) change (#104401)

This commit is contained in:
Mustafa Sencer Özcan
2025-04-25 13:43:35 +02:00
committed by GitHub
parent 43d0053c80
commit ebf3a8d205
7 changed files with 23 additions and 1 deletions
+1 -1
View File
@@ -455,7 +455,7 @@ require (
github.com/mithrandie/ternary v1.1.1 // indirect github.com/mithrandie/ternary v1.1.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect github.com/moby/spdystream v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/mschoch/smat v0.2.0 // indirect github.com/mschoch/smat v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
+4
View File
@@ -164,6 +164,10 @@ func SetDualWritingMode(
return Mode0, errDualWriterSetCurrentMode return Mode0, errDualWriterSetCurrentMode
} }
case cfg.Mode >= Mode3 && currentMode < Mode3: case cfg.Mode >= Mode3 && currentMode < Mode3:
if cfg.SkipDataSync {
return currentMode, nil
}
// Transitioning to Mode3 or higher requires data synchronization. // Transitioning to Mode3 or higher requires data synchronization.
cfgModeTmp := cfg.Mode cfgModeTmp := cfg.Mode
// Before running the sync, set the syncer config to the current mode, as we have to run the syncer // Before running the sync, set the syncer config to the current mode, as we have to run the syncer
+1
View File
@@ -36,6 +36,7 @@ type SyncerConfig struct {
LegacyStorage Storage LegacyStorage Storage
Storage Storage Storage Storage
ServerLockService ServerLockService ServerLockService ServerLockService
SkipDataSync bool
DataSyncerInterval time.Duration DataSyncerInterval time.Duration
DataSyncerRecordsLimit int DataSyncerRecordsLimit int
+9
View File
@@ -20,6 +20,7 @@ func TestSetDualWritingMode(t *testing.T) {
kvStore *fakeNamespacedKV kvStore *fakeNamespacedKV
desiredMode DualWriterMode desiredMode DualWriterMode
expectedMode DualWriterMode expectedMode DualWriterMode
skipDataSync bool
serverLockError error serverLockError error
} }
tests := tests :=
@@ -61,6 +62,13 @@ func TestSetDualWritingMode(t *testing.T) {
expectedMode: Mode2, expectedMode: Mode2,
serverLockError: fmt.Errorf("lock already exists"), serverLockError: fmt.Errorf("lock already exists"),
}, },
{
name: "should keep mode2 when trying to go from mode2 to mode3 and migration is disabled",
kvStore: &fakeNamespacedKV{data: map[string]string{"playlist.grafana.app/playlists": "2"}, namespace: "storage.dualwriting"},
desiredMode: Mode3,
expectedMode: Mode2,
skipDataSync: true,
},
} }
for _, tt := range tests { for _, tt := range tests {
@@ -86,6 +94,7 @@ func TestSetDualWritingMode(t *testing.T) {
Storage: us, Storage: us,
Kind: "playlist.grafana.app/playlists", Kind: "playlist.grafana.app/playlists",
Mode: tt.desiredMode, Mode: tt.desiredMode,
SkipDataSync: tt.skipDataSync,
ServerLockService: serverLockSvc, ServerLockService: serverLockSvc,
RequestInfo: &request.RequestInfo{}, RequestInfo: &request.RequestInfo{},
Reg: p, Reg: p,
+3
View File
@@ -315,6 +315,7 @@ func InstallAPIs(
var ( var (
dualWriterPeriodicDataSyncJobEnabled bool dualWriterPeriodicDataSyncJobEnabled bool
dualWriterMigrationDataSyncDisabled bool
dataSyncerInterval = time.Hour dataSyncerInterval = time.Hour
dataSyncerRecordsLimit = 1000 dataSyncerRecordsLimit = 1000
) )
@@ -323,6 +324,7 @@ func InstallAPIs(
if resourceExists { if resourceExists {
mode = resourceConfig.DualWriterMode mode = resourceConfig.DualWriterMode
dualWriterPeriodicDataSyncJobEnabled = resourceConfig.DualWriterPeriodicDataSyncJobEnabled dualWriterPeriodicDataSyncJobEnabled = resourceConfig.DualWriterPeriodicDataSyncJobEnabled
dualWriterMigrationDataSyncDisabled = resourceConfig.DualWriterMigrationDataSyncDisabled
dataSyncerInterval = resourceConfig.DataSyncerInterval dataSyncerInterval = resourceConfig.DataSyncerInterval
dataSyncerRecordsLimit = resourceConfig.DataSyncerRecordsLimit dataSyncerRecordsLimit = resourceConfig.DataSyncerRecordsLimit
} }
@@ -343,6 +345,7 @@ func InstallAPIs(
Kind: key, Kind: key,
RequestInfo: requestInfo, RequestInfo: requestInfo,
Mode: mode, Mode: mode,
SkipDataSync: dualWriterMigrationDataSyncDisabled,
LegacyStorage: legacy, LegacyStorage: legacy,
Storage: storage, Storage: storage,
ServerLockService: serverLock, ServerLockService: serverLock,
+1
View File
@@ -556,6 +556,7 @@ type Cfg struct {
type UnifiedStorageConfig struct { type UnifiedStorageConfig struct {
DualWriterMode rest.DualWriterMode DualWriterMode rest.DualWriterMode
DualWriterPeriodicDataSyncJobEnabled bool DualWriterPeriodicDataSyncJobEnabled bool
DualWriterMigrationDataSyncDisabled bool
// DataSyncerInterval defines how often the data syncer should run for a resource on the grafana instance. // DataSyncerInterval defines how often the data syncer should run for a resource on the grafana instance.
DataSyncerInterval time.Duration DataSyncerInterval time.Duration
// DataSyncerRecordsLimit defines how many records will be processed at max during a sync invocation. // DataSyncerRecordsLimit defines how many records will be processed at max during a sync invocation.
+4
View File
@@ -30,6 +30,9 @@ func (cfg *Cfg) setUnifiedStorageConfig() {
// parse dualWriter periodic data syncer config // parse dualWriter periodic data syncer config
dualWriterPeriodicDataSyncJobEnabled := section.Key("dualWriterPeriodicDataSyncJobEnabled").MustBool(false) dualWriterPeriodicDataSyncJobEnabled := section.Key("dualWriterPeriodicDataSyncJobEnabled").MustBool(false)
// parse dualWriter migration data sync disabled from resource section
dualWriterMigrationDataSyncDisabled := section.Key("dualWriterMigrationDataSyncDisabled").MustBool(false)
// parse dataSyncerRecordsLimit from resource section // parse dataSyncerRecordsLimit from resource section
dataSyncerRecordsLimit := section.Key("dataSyncerRecordsLimit").MustInt(1000) dataSyncerRecordsLimit := section.Key("dataSyncerRecordsLimit").MustInt(1000)
@@ -39,6 +42,7 @@ func (cfg *Cfg) setUnifiedStorageConfig() {
storageConfig[resourceName] = UnifiedStorageConfig{ storageConfig[resourceName] = UnifiedStorageConfig{
DualWriterMode: rest.DualWriterMode(dualWriterMode), DualWriterMode: rest.DualWriterMode(dualWriterMode),
DualWriterPeriodicDataSyncJobEnabled: dualWriterPeriodicDataSyncJobEnabled, DualWriterPeriodicDataSyncJobEnabled: dualWriterPeriodicDataSyncJobEnabled,
DualWriterMigrationDataSyncDisabled: dualWriterMigrationDataSyncDisabled,
DataSyncerRecordsLimit: dataSyncerRecordsLimit, DataSyncerRecordsLimit: dataSyncerRecordsLimit,
DataSyncerInterval: dataSyncerInterval, DataSyncerInterval: dataSyncerInterval,
} }