diff --git a/cdc/api/middleware/middleware.go b/cdc/api/middleware/middleware.go index ce3ee800af..0869c1f2d0 100644 --- a/cdc/api/middleware/middleware.go +++ b/cdc/api/middleware/middleware.go @@ -15,6 +15,7 @@ package middleware import ( "net/http" + "slices" "time" "github.com/gin-gonic/gin" @@ -152,14 +153,8 @@ func verify(ctx *gin.Context, up *upstream.Upstream) error { return errors.ErrCredentialNotFound.GenWithStackByArgs(errMsg) } - allowed := false serverCfg := config.GetGlobalServerConfig() - for _, user := range serverCfg.Security.ClientAllowedUser { - if user == username { - allowed = true - break - } - } + allowed := slices.Contains(serverCfg.Security.ClientAllowedUser, username) if !allowed { errMsg := "The user is not allowed." if username == "" { diff --git a/cdc/api/util.go b/cdc/api/util.go index 1a4ea517dc..91d14a8160 100644 --- a/cdc/api/util.go +++ b/cdc/api/util.go @@ -104,7 +104,7 @@ func WriteError(w http.ResponseWriter, statusCode int, err error) { } // WriteData write data to response with http status code 200 -func WriteData(w http.ResponseWriter, data interface{}) { +func WriteData(w http.ResponseWriter, data any) { js, err := json.MarshalIndent(data, "", " ") if err != nil { log.Error("invalid json data", zap.Any("data", data), zap.Error(err)) diff --git a/cdc/api/v2/model.go b/cdc/api/v2/model.go index eb20e3e979..5c28aef440 100644 --- a/cdc/api/v2/model.go +++ b/cdc/api/v2/model.go @@ -162,7 +162,7 @@ func (d JSONDuration) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshal json value to wrapped duration func (d *JSONDuration) UnmarshalJSON(b []byte) error { - var v interface{} + var v any if err := json.Unmarshal(b, &v); err != nil { return err } diff --git a/cdc/api/v2/unsafe_test.go b/cdc/api/v2/unsafe_test.go index b07dd60094..7a37c5b867 100644 --- a/cdc/api/v2/unsafe_test.go +++ b/cdc/api/v2/unsafe_test.go @@ -80,8 +80,7 @@ func TestCDCMetaData(t *testing.T) { } func TestWithUpstreamConfig(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() upManager := upstream.NewManager(ctx, upstream.CaptureTopologyCfg{GCServiceID: "abc"}) upManager.AddUpstream(&model.UpstreamInfo{ ID: uint64(1), diff --git a/cdc/capture/capture_test.go b/cdc/capture/capture_test.go index d533b9f0cc..e502d7c097 100644 --- a/cdc/capture/capture_test.go +++ b/cdc/capture/capture_test.go @@ -64,12 +64,10 @@ func TestReset(t *testing.T) { // simulate network isolation scenarios etcdServer.Close() wg := sync.WaitGroup{} - wg.Add(1) - go func() { + wg.Go(func() { _, err = cp.reset(ctx) require.Regexp(t, ".*context canceled.*", err) - wg.Done() - }() + }) time.Sleep(100 * time.Millisecond) info, err := cp.Info() require.Nil(t, err) @@ -230,15 +228,13 @@ func TestCampaignLiveness(t *testing.T) { // Force set alive. cp.liveness = model.LivenessCaptureAlive wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { // Grant campaign g := <-me.campaignRequestCh // Set liveness to stopping cp.liveness.Store(model.LivenessCaptureStopping) me.campaignGrantCh <- g - }() + }) err = cp.campaignOwner(ctx, globalVars) require.Nil(t, err) require.True(t, me.campaignFlag) diff --git a/cdc/entry/mounter.go b/cdc/entry/mounter.go index 07fd0baacb..9afac0ab5a 100644 --- a/cdc/entry/mounter.go +++ b/cdc/entry/mounter.go @@ -355,7 +355,7 @@ func datum2Column( colDatum, exist := datums[colID] var ( - colValue interface{} + colValue any size int warn string err error @@ -459,7 +459,7 @@ func (m *mounter) verifyColumnChecksum( return checksum, true, nil } -func newDatum(value interface{}, ft types.FieldType) (types.Datum, error) { +func newDatum(value any, ft types.FieldType) (types.Datum, error) { if value == nil { return types.NewDatum(nil), nil } @@ -770,7 +770,7 @@ func sizeOfBytes(b []byte) int { // formatColVal return interface{} need to meet the same requirement as getDefaultOrZeroValue func formatColVal(datum types.Datum, col *timodel.ColumnInfo) ( - value interface{}, size int, warn string, err error, + value any, size int, warn string, err error, ) { if datum.IsNull() { return nil, 0, "", nil diff --git a/cdc/entry/mounter_test.go b/cdc/entry/mounter_test.go index 7b01037c3d..3ebef98ba0 100644 --- a/cdc/entry/mounter_test.go +++ b/cdc/entry/mounter_test.go @@ -59,7 +59,7 @@ func TestMounterDisableOldValue(t *testing.T) { tableName string createTableDDL string // [] for rows, []interface{} for columns. - values [][]interface{} + values [][]any // [] for table partition if there is any, // []int for approximateBytes of rows. putApproximateBytes [][]int @@ -67,25 +67,25 @@ func TestMounterDisableOldValue(t *testing.T) { }{{ tableName: "simple", createTableDDL: "create table simple(id int primary key)", - values: [][]interface{}{{1}, {2}, {3}, {4}, {5}}, + values: [][]any{{1}, {2}, {3}, {4}, {5}}, putApproximateBytes: [][]int{{346, 346, 346, 346, 346}}, delApproximateBytes: [][]int{{346, 346, 346, 346, 346}}, }, { tableName: "no_pk", createTableDDL: "create table no_pk(id int not null unique key)", - values: [][]interface{}{{1}, {2}, {3}, {4}, {5}}, + values: [][]any{{1}, {2}, {3}, {4}, {5}}, putApproximateBytes: [][]int{{345, 345, 345, 345, 345}}, delApproximateBytes: [][]int{{217, 217, 217, 217, 217}}, }, { tableName: "many_index", createTableDDL: "create table many_index(id int not null unique key, c1 int unique key, c2 int, INDEX (c2))", - values: [][]interface{}{{1, 1, 1}, {2, 2, 2}, {3, 3, 3}, {4, 4, 4}, {5, 5, 5}}, + values: [][]any{{1, 1, 1}, {2, 2, 2}, {3, 3, 3}, {4, 4, 4}, {5, 5, 5}}, putApproximateBytes: [][]int{{638, 638, 638, 638, 638}}, delApproximateBytes: [][]int{{254, 254, 254, 254, 254}}, }, { tableName: "default_value", createTableDDL: "create table default_value(id int primary key, c1 int, c2 int not null default 5, c3 varchar(20), c4 varchar(20) not null default '666')", - values: [][]interface{}{{1}, {2}, {3}, {4}, {5}}, + values: [][]any{{1}, {2}, {3}, {4}, {5}}, putApproximateBytes: [][]int{{676, 676, 676, 676, 676}}, delApproximateBytes: [][]int{{353, 353, 353, 353, 353}}, }, { @@ -105,7 +105,7 @@ func TestMounterDisableOldValue(t *testing.T) { PARTITION p2 VALUES LESS THAN (15), PARTITION p3 VALUES LESS THAN (20) )`, - values: [][]interface{}{ + values: [][]any{ {1, "aa", "bb", 12, 12}, {6, "aac", "bab", 51, 51}, {11, "aad", "bsb", 71, 61}, @@ -127,7 +127,7 @@ func TestMounterDisableOldValue(t *testing.T) { constraint pk primary key (id) );`, - values: [][]interface{}{ + values: [][]any{ {1, 1, 2, 3, 4, 5}, {2}, {3, 3, 4, 5, 6, 7}, @@ -156,7 +156,7 @@ func TestMounterDisableOldValue(t *testing.T) { constraint pk primary key (id) );`, - values: [][]interface{}{ + values: [][]any{ {1}, { 2, "89504E470D0A1A0A", "89504E470D0A1A0A", "89504E470D0A1A0A", "89504E470D0A1A0A", "89504E470D0A1A0A", @@ -191,7 +191,7 @@ func TestMounterDisableOldValue(t *testing.T) { constraint pk primary key (id) );`, - values: [][]interface{}{ + values: [][]any{ {1}, {2, "2020-02-20", "2020-02-20 02:20:20", "2020-02-20 02:20:20", "02:20:20", "2020"}, }, @@ -208,7 +208,7 @@ func TestMounterDisableOldValue(t *testing.T) { constraint pk primary key (id) );`, - values: [][]interface{}{ + values: [][]any{ {1}, {2, "2020.0202", "2020.0303", "2020.0404"}, }, @@ -226,7 +226,7 @@ func TestMounterDisableOldValue(t *testing.T) { constraint pk primary key (id) );`, - values: [][]interface{}{ + values: [][]any{ {1}, {2, "a", "a,c", 888, `{"aa":"bb"}`}, }, @@ -235,7 +235,7 @@ func TestMounterDisableOldValue(t *testing.T) { }, { tableName: "clustered_index1", createTableDDL: "CREATE TABLE clustered_index1 (id VARCHAR(255) PRIMARY KEY, data INT);", - values: [][]interface{}{ + values: [][]any{ {"hhh"}, {"你好😘", 666}, {"世界🤪", 888}, @@ -245,7 +245,7 @@ func TestMounterDisableOldValue(t *testing.T) { }, { tableName: "clustered_index2", createTableDDL: "CREATE TABLE clustered_index2 (id VARCHAR(255), data INT, ddaa date, PRIMARY KEY (id, data, ddaa), UNIQUE KEY (id, data, ddaa));", - values: [][]interface{}{ + values: [][]any{ {"你好😘", 666, "2020-11-20"}, {"世界🤪", 888, "2020-05-12"}, }, @@ -260,7 +260,7 @@ func TestMounterDisableOldValue(t *testing.T) { func testMounterDisableOldValue(t *testing.T, tc struct { tableName string createTableDDL string - values [][]interface{} + values [][]any putApproximateBytes [][]int delApproximateBytes [][]int }, @@ -338,12 +338,12 @@ func testMounterDisableOldValue(t *testing.T, tc struct { if len(row.Columns) != 0 { checkSQL, params := prepareCheckSQL(t, tc.tableName, row.GetColumns()) result := tk.MustQuery(checkSQL, params...) - result.Check([][]interface{}{{"1"}}) + result.Check([][]any{{"1"}}) } if len(row.PreColumns) != 0 { checkSQL, params := prepareCheckSQL(t, tc.tableName, row.GetPreColumns()) result := tk.MustQuery(checkSQL, params...) - result.Check([][]interface{}{{"1"}}) + result.Check([][]any{{"1"}}) } }) return rows @@ -387,7 +387,7 @@ func prepareInsertSQL(t *testing.T, tableInfo *model.TableInfo, columnLens int) var sb strings.Builder _, err := sb.WriteString("INSERT INTO " + tableInfo.Name.O + "(") require.Nil(t, err) - for i := 0; i < columnLens; i++ { + for i := range columnLens { col := tableInfo.Columns[i] if i != 0 { _, err = sb.WriteString(", ") @@ -398,7 +398,7 @@ func prepareInsertSQL(t *testing.T, tableInfo *model.TableInfo, columnLens int) } _, err = sb.WriteString(") VALUES (") require.Nil(t, err) - for i := 0; i < columnLens; i++ { + for i := range columnLens { if i != 0 { _, err = sb.WriteString(", ") require.Nil(t, err) @@ -411,11 +411,11 @@ func prepareInsertSQL(t *testing.T, tableInfo *model.TableInfo, columnLens int) return sb.String() } -func prepareCheckSQL(t *testing.T, tableName string, cols []*model.Column) (string, []interface{}) { +func prepareCheckSQL(t *testing.T, tableName string, cols []*model.Column) (string, []any) { var sb strings.Builder _, err := sb.WriteString("SELECT count(1) FROM " + tableName + " WHERE ") require.Nil(t, err) - params := make([]interface{}, 0, len(cols)) + params := make([]any, 0, len(cols)) for i, col := range cols { // Since float type has precision problem, so skip it to avoid compare float number. if col == nil || col.Type == mysql.TypeFloat { @@ -610,7 +610,7 @@ func TestGetDefaultZeroValue(t *testing.T) { testCases := []struct { Name string ColInfo timodel.ColumnInfo - Res interface{} + Res any }{ { Name: "mysql flag null", @@ -1352,7 +1352,7 @@ func TestDecodeEventIgnoreRow(t *testing.T) { type testCase struct { schema string table string - columns []interface{} + columns []any ignored bool } @@ -1360,20 +1360,20 @@ func TestDecodeEventIgnoreRow(t *testing.T) { { schema: "test", table: "student", - columns: []interface{}{1, "dongmen", 20, "male"}, + columns: []any{1, "dongmen", 20, "male"}, ignored: false, }, { schema: "test", table: "computer", - columns: []interface{}{1, "apple", 19999}, + columns: []any{1, "apple", 19999}, ignored: false, }, // This case should be ignored by its table name. { schema: "test", table: "poet", - columns: []interface{}{1, "李白", "静夜思"}, + columns: []any{1, "李白", "静夜思"}, ignored: true, }, } @@ -1642,14 +1642,14 @@ func TestNewDMRowChange(t *testing.T) { recoveredTI := model.BuildTiDBTableInfo(cdcTableInfo.TableName.Table, cols, cdcTableInfo.IndexColumnsOffset) require.Equal(t, c.recovered, showCreateTable(t, recoveredTI)) tableName := &model.TableName{Schema: "db", Table: "t1"} - rowChange := sqlmodel.NewRowChange(tableName, nil, []interface{}{1, 1, 2}, nil, recoveredTI, nil, nil) + rowChange := sqlmodel.NewRowChange(tableName, nil, []any{1, 1, 2}, nil, recoveredTI, nil, nil) sqlGot, argsGot := rowChange.GenSQL(sqlmodel.DMLDelete) require.Equal(t, "DELETE FROM `db`.`t1` WHERE `a1` = ? AND `a3` = ? LIMIT 1", sqlGot) - require.Equal(t, []interface{}{1, 2}, argsGot) + require.Equal(t, []any{1, 2}, argsGot) sqlGot, argsGot = sqlmodel.GenDeleteSQL(rowChange, rowChange) require.Equal(t, "DELETE FROM `db`.`t1` WHERE (`a1` = ? AND `a3` = ?) OR (`a1` = ? AND `a3` = ?)", sqlGot) - require.Equal(t, []interface{}{1, 2, 1, 2}, argsGot) + require.Equal(t, []any{1, 2, 1, 2}, argsGot) } } diff --git a/cdc/entry/schema/snapshot.go b/cdc/entry/schema/snapshot.go index f91b351f90..182dbcdff6 100644 --- a/cdc/entry/schema/snapshot.go +++ b/cdc/entry/schema/snapshot.go @@ -1343,7 +1343,7 @@ type versionedID struct { id int64 tag uint64 // A transform of timestamp to reverse sort versions. // the associated entity pointer. - target interface{} + target any } func versionedEntityNameLess(v1, v2 versionedEntityName) bool { @@ -1370,18 +1370,18 @@ func newVersionedEntityName(prefix int64, entity string, tag uint64) versionedEn // newVersionedID creates an instance with target nil, which means it's deleted from the // associated snapshot. func newVersionedID(id int64, tag uint64) versionedID { - var target interface{} = nil + var target any = nil return versionedID{id, tag, target} } -func targetToTableInfo(target interface{}) *model.TableInfo { +func targetToTableInfo(target any) *model.TableInfo { if target == nil { return nil } return target.(*model.TableInfo) } -func targetToDBInfo(target interface{}) *timodel.DBInfo { +func targetToDBInfo(target any) *timodel.DBInfo { if target == nil { return nil } diff --git a/cdc/entry/schema_storage_test.go b/cdc/entry/schema_storage_test.go index 1b973d0d8e..43a7d9c959 100644 --- a/cdc/entry/schema_storage_test.go +++ b/cdc/entry/schema_storage_test.go @@ -441,7 +441,7 @@ func TestHandleRenameTables(t *testing.T) { newTableNames := []pmodel.CIStr{pmodel.NewCIStr("x"), pmodel.NewCIStr("y")} oldTableNames := []pmodel.CIStr{pmodel.NewCIStr("oldx"), pmodel.NewCIStr("oldy")} oldSchemaNames := []pmodel.CIStr{pmodel.NewCIStr("db_1"), pmodel.NewCIStr("db_2")} - args := []interface{}{oldSchemaIDs, newSchemaIDs, newTableNames, oldTableIDs, oldSchemaNames, oldTableNames} + args := []any{oldSchemaIDs, newSchemaIDs, newTableNames, oldTableIDs, oldSchemaNames, oldTableNames} rawArgs, err := json.Marshal(args) require.Nil(t, err) job := &timodel.Job{ diff --git a/cdc/entry/schema_test.go b/cdc/entry/schema_test.go index 1e7474fc1b..93335d69f8 100644 --- a/cdc/entry/schema_test.go +++ b/cdc/entry/schema_test.go @@ -16,7 +16,7 @@ package entry import ( "context" "fmt" - "sort" + "slices" "testing" timodel "github.com/pingcap/tidb/pkg/meta/model" @@ -78,9 +78,7 @@ func TestAllPhysicalTables(t *testing.T) { expectedTableIDs = append(expectedTableIDs, p.ID) } sortTableIDs := func(tableIDs []model.TableID) { - sort.Slice(tableIDs, func(i, j int) bool { - return tableIDs[i] < tableIDs[j] - }) + slices.Sort(tableIDs) } sortTableIDs(expectedTableIDs) tableIDs, err = schema.AllPhysicalTables(context.Background(), job.BinlogInfo.FinishedTS) diff --git a/cdc/entry/schema_test_helper.go b/cdc/entry/schema_test_helper.go index 36f21b6e12..5d8b4cf26e 100644 --- a/cdc/entry/schema_test_helper.go +++ b/cdc/entry/schema_test_helper.go @@ -131,7 +131,7 @@ func (s *SchemaTestHelper) DDL2Job(ddl string) *timodel.Job { args := &timodel.RenameTablesArgs{ RenameTableInfos: make([]*timodel.RenameTableArgs, 0, tableNum), } - for i := 0; i < tableNum; i++ { + for i := range tableNum { args.RenameTableInfos = append(args.RenameTableInfos, &timodel.RenameTableArgs{ OldSchemaID: res.SchemaID, NewSchemaID: res.SchemaID, @@ -238,7 +238,7 @@ func (s *SchemaTestHelper) DDL2Event(ddl string) *model.DDLEvent { args := &timodel.RenameTablesArgs{ RenameTableInfos: make([]*timodel.RenameTableArgs, 0, tableNum), } - for i := 0; i < tableNum; i++ { + for i := range tableNum { args.RenameTableInfos = append(args.RenameTableInfos, &timodel.RenameTableArgs{ OldSchemaID: res.SchemaID, NewSchemaID: res.SchemaID, diff --git a/cdc/kv/matcher.go b/cdc/kv/matcher.go index bf61039269..2307f092f4 100644 --- a/cdc/kv/matcher.go +++ b/cdc/kv/matcher.go @@ -98,7 +98,7 @@ func (m *matcher) matchCachedRow(initialized bool) []*cdcpb.Event_Row { cachedCommit := m.cachedCommit m.cachedCommit = nil top := 0 - for i := 0; i < len(cachedCommit); i++ { + for i := range cachedCommit { cacheEntry := cachedCommit[i] ok := m.matchRow(cacheEntry, true) if !ok { @@ -131,7 +131,7 @@ func (m *matcher) matchCachedRollbackRow(initialized bool) { } rollback := m.cachedRollback m.cachedRollback = nil - for i := 0; i < len(rollback); i++ { + for i := range rollback { cacheEntry := rollback[i] m.rollbackRow(cacheEntry) } diff --git a/cdc/kv/regionlock/region_range_lock.go b/cdc/kv/regionlock/region_range_lock.go index 51ed495d2c..42a37a6669 100644 --- a/cdc/kv/regionlock/region_range_lock.go +++ b/cdc/kv/regionlock/region_range_lock.go @@ -78,7 +78,7 @@ type rangeLockEntry struct { lockedRangeState LockedRangeState // waiterSignalChs is a list of channels that are used to // notify the waiter of this lock entry that the lock is released. - waiterSignalChs []chan<- interface{} + waiterSignalChs []chan<- any } func rangeLockEntryWithKey(key []byte) *rangeLockEntry { @@ -407,7 +407,7 @@ func (l *RangeLock) getOverlappedLockEntries(startKey, endKey []byte, regionID u // - If the current region's version is stale, it will return LockRangeStatusStale and the overlapping ranges to the caller. // - If the current region's version is not stale, it will return LockRangeStatusWait and the overlapping ranges to the caller, // and the caller should wait for the overlapping ranges to be released and retry to lock the rest of the range. -func (l *RangeLock) tryLockRange(startKey, endKey []byte, regionID, regionVersion uint64) (LockRangeResult, []<-chan interface{}) { +func (l *RangeLock) tryLockRange(startKey, endKey []byte, regionID, regionVersion uint64) (LockRangeResult, []<-chan any) { l.mu.Lock() defer l.mu.Unlock() if l.stopped { @@ -501,10 +501,10 @@ func (l *RangeLock) tryLockRange(startKey, endKey []byte, regionID, regionVersio }, nil } - var lockReleaseSignalChs []<-chan interface{} + var lockReleaseSignalChs []<-chan any for _, r := range overlappedRangeLocks { - ch := make(chan interface{}, 1) + ch := make(chan any, 1) lockReleaseSignalChs = append(lockReleaseSignalChs, ch) r.waiterSignalChs = append(r.waiterSignalChs, ch) } diff --git a/cdc/kv/shared_client_test.go b/cdc/kv/shared_client_test.go index b6db06e5c8..ae1c2ef009 100644 --- a/cdc/kv/shared_client_test.go +++ b/cdc/kv/shared_client_test.go @@ -78,12 +78,10 @@ func newMockServiceSpecificAddr( grpcServer = grpc.NewServer(grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp)) // grpcServer is the server, srv is the service cdcpb.RegisterChangeDataServer(grpcServer, srv) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := grpcServer.Serve(lis) require.Nil(t, err) - }() + }) return } @@ -206,12 +204,10 @@ func TestConnectToOfflineOrFailedTiKV(t *testing.T) { wg.Wait() }() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) subID := client.AllocSubscriptionID() span := tablepb.Span{TableID: 1, StartKey: []byte("a"), EndKey: []byte("b")} @@ -315,12 +311,10 @@ func TestGetStoreFailed(t *testing.T) { wg.Wait() }() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) failpoint.Enable("github.com/pingcap/tiflow/pkg/version/GetStoreFailed", `return(true)`) subID := client.AllocSubscriptionID() @@ -372,16 +366,14 @@ func newMockChangeDataServer(ch chan *cdcpb.ChangeDataEvent) *mockChangeDataServ func (m *mockChangeDataServer) EventFeed(s cdcpb.ChangeData_EventFeedServer) error { closed := make(chan struct{}) - m.wg.Add(1) - go func() { - defer m.wg.Done() + m.wg.Go(func() { defer close(closed) for { if _, err := s.Recv(); err != nil { return } } - }() + }) m.wg.Add(1) defer m.wg.Done() ticker := time.NewTicker(20 * time.Millisecond) diff --git a/cdc/kv/shared_region_worker_test.go b/cdc/kv/shared_region_worker_test.go index 9740280042..a5d51b912b 100644 --- a/cdc/kv/shared_region_worker_test.go +++ b/cdc/kv/shared_region_worker_test.go @@ -62,8 +62,7 @@ func newSharedClientForTestSharedRegionWorker() *SharedClient { // TiKV: [Scan Start] [Send Prewrite2] [Send Commit] [Send Prewrite1] [Send Init] // TiCDC: [Recv Prewrite2] [Recv Commit] [Recv Prewrite1] [Recv Init] func TestSharedRegionWokerHandleEventEntryEventOutOfOrder(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() client := newSharedClientForTestSharedRegionWorker() defer client.Close() @@ -168,8 +167,7 @@ func TestSharedRegionWokerHandleEventEntryEventOutOfOrder(t *testing.T) { } func TestSharedRegionWorkerHandleResolvedTs(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() client := newSharedClientForTestSharedRegionWorker() defer client.Close() diff --git a/cdc/kv/sharedconn/conn_and_client_test.go b/cdc/kv/sharedconn/conn_and_client_test.go index 797eb09560..728932cf28 100644 --- a/cdc/kv/sharedconn/conn_and_client_test.go +++ b/cdc/kv/sharedconn/conn_and_client_test.go @@ -37,11 +37,9 @@ func TestConnAndClientPool(t *testing.T) { var wg sync.WaitGroup defer wg.Wait() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.Nil(t, runGrpcService(&srv{}, &addr, service)) - }() + }) svc := <-service require.NotNil(t, svc) @@ -85,11 +83,9 @@ func TestConnAndClientPoolForV2(t *testing.T) { var wg sync.WaitGroup defer wg.Wait() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.Nil(t, runGrpcService(&srv{v2: true}, &addr, service)) - }() + }) svc := <-service require.NotNil(t, svc) @@ -127,11 +123,9 @@ func TestConnectToUnavailable(t *testing.T) { var wg sync.WaitGroup defer wg.Wait() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.Nil(t, runGrpcService(&srv{}, &addr, service)) - }() + }) svc := <-service require.NotNil(t, svc) @@ -157,18 +151,15 @@ func TestCancelStream(t *testing.T) { var addr string var wg sync.WaitGroup defer wg.Wait() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.Nil(t, runGrpcService(&srv{}, &addr, service)) - }() + }) svc := <-service require.NotNil(t, svc) defer svc.GracefulStop() - connCtx, connCancel := context.WithCancel(context.Background()) - defer connCancel() + connCtx := t.Context() pool := newConnAndClientPool(&security.Credential{}, nil, 1) conn, err := pool.connect(connCtx, addr) diff --git a/cdc/model/codec/codec.go b/cdc/model/codec/codec.go index fbba781c2d..6eef59fbc8 100644 --- a/cdc/model/codec/codec.go +++ b/cdc/model/codec/codec.go @@ -123,7 +123,7 @@ func UnmarshalRedoLog(bts []byte) (r *model.RedoLog, o []byte, err error) { } shouldBeV1 := false - for i := 0; i < versionPrefixLength; i++ { + for i := range versionPrefixLength { if bts[i] != versionPrefix[i] { shouldBeV1 = true break diff --git a/cdc/model/codec/v1/codec.go b/cdc/model/codec/v1/codec.go index 22bb5d58b6..6b5a8425d3 100644 --- a/cdc/model/codec/v1/codec.go +++ b/cdc/model/codec/v1/codec.go @@ -80,8 +80,8 @@ type Column struct { Type byte `json:"type" msg:"type"` Charset string `json:"charset" msg:"charset"` Flag model.ColumnFlagType `json:"flag" msg:"-"` - Value interface{} `json:"value" msg:"value"` - Default interface{} `json:"default" msg:"-"` + Value any `json:"value" msg:"value"` + Default any `json:"default" msg:"-"` // ApproximateBytes is approximate bytes consumed by the column. ApproximateBytes int `json:"-"` diff --git a/cdc/model/errors.go b/cdc/model/errors.go index 9a7129a789..66d4bf05d3 100644 --- a/cdc/model/errors.go +++ b/cdc/model/errors.go @@ -41,7 +41,7 @@ func (e RunningError) Value() (driver.Value, error) { } // Scan implements the sql.Scanner interface -func (e *RunningError) Scan(value interface{}) error { +func (e *RunningError) Scan(value any) error { b, ok := value.([]byte) if !ok { return errors.New("type assertion to []byte failed") diff --git a/cdc/model/kv.go b/cdc/model/kv.go index 14e2672a4b..8dfcc56a20 100644 --- a/cdc/model/kv.go +++ b/cdc/model/kv.go @@ -46,7 +46,7 @@ type RegionFeedEvent struct { } // GetValue returns the underlying value -func (e *RegionFeedEvent) GetValue() interface{} { +func (e *RegionFeedEvent) GetValue() any { if e.Val != nil { return e.Val } else if e.Resolved != nil { diff --git a/cdc/model/owner.go b/cdc/model/owner.go index 4dd579ba89..6b965ae569 100644 --- a/cdc/model/owner.go +++ b/cdc/model/owner.go @@ -16,6 +16,7 @@ package model import ( "encoding/json" "fmt" + "strings" "github.com/pingcap/errors" timodel "github.com/pingcap/tidb/pkg/meta/model" @@ -257,14 +258,19 @@ type ProcessorsInfos map[CaptureID]*TaskStatus // String implements fmt.Stringer interface. func (p ProcessorsInfos) String() string { - s := "{" + var s strings.Builder + s.WriteString("{") for id, sinfo := range p { - s += fmt.Sprintf("%s: %+v,", id, *sinfo) + if sinfo == nil { + fmt.Fprintf(&s, "%s: nil,", id) + } else { + fmt.Fprintf(&s, "%s: %+v,", id, *sinfo) + } } - s += "}" + s.WriteString("}") - return s + return s.String() } // ChangeFeedStatus stores information about a ChangeFeed diff --git a/cdc/model/sink.go b/cdc/model/sink.go index 491093bd23..0081b1b32e 100644 --- a/cdc/model/sink.go +++ b/cdc/model/sink.go @@ -671,7 +671,7 @@ type Column struct { Charset string `msg:"charset"` Collation string `msg:"collation"` Flag ColumnFlagType `msg:"-"` - Value interface{} `msg:"-"` + Value any `msg:"-"` // ApproximateBytes is approximate bytes consumed by the column. ApproximateBytes int `msg:"-"` @@ -682,8 +682,8 @@ type ColumnData struct { // ColumnID may be just a mock id, because we don't store it in redo log. // So after restore from redo log, we need to give every a column a mock id. // The only guarantee is that the column id is unique in a RowChangedEvent - ColumnID int64 `json:"column_id" msg:"column_id"` - Value interface{} `json:"value" msg:"-"` + ColumnID int64 `json:"column_id" msg:"column_id"` + Value any `json:"value" msg:"-"` // ApproximateBytes is approximate bytes consumed by the column. ApproximateBytes int `json:"-" msg:"-"` @@ -692,7 +692,7 @@ type ColumnData struct { // RedoColumn stores Column change type RedoColumn struct { // Fields from Column and can't be marshaled directly in Column. - Value interface{} `msg:"column"` + Value any `msg:"column"` // msgp transforms empty byte slice into nil, PTAL msgp#247. ValueIsEmptyBytes bool `msg:"value-is-empty-bytes"` Flag uint64 `msg:"flag"` @@ -1018,7 +1018,7 @@ func BuildTiDBTableInfoImpl( } // ColumnValueString returns the string representation of the column value -func ColumnValueString(c interface{}) string { +func ColumnValueString(c any) string { var data string switch v := c.(type) { case nil: @@ -1382,7 +1382,7 @@ func (x ColumnDataX) GetFlag() ColumnFlagType { } // GetDefaultValue return default value. -func (x ColumnDataX) GetDefaultValue() interface{} { +func (x ColumnDataX) GetDefaultValue() any { return x.info.GetDefaultValue() } diff --git a/cdc/model/sink_test.go b/cdc/model/sink_test.go index d80f2aeba3..efedd63697 100644 --- a/cdc/model/sink_test.go +++ b/cdc/model/sink_test.go @@ -112,26 +112,26 @@ func TestRowChangedEventFuncs(t *testing.T) { func TestColumnValueString(t *testing.T) { t.Parallel() testCases := []struct { - val interface{} + val any expected string }{ - {interface{}(nil), "null"}, - {interface{}(true), "1"}, - {interface{}(false), "0"}, - {interface{}(123), "123"}, - {interface{}(int8(-123)), "-123"}, - {interface{}(int16(-123)), "-123"}, - {interface{}(int32(-123)), "-123"}, - {interface{}(int64(-123)), "-123"}, - {interface{}(uint8(123)), "123"}, - {interface{}(uint16(123)), "123"}, - {interface{}(uint32(123)), "123"}, - {interface{}(uint64(123)), "123"}, - {interface{}(float32(123.01)), "123.01"}, - {interface{}(float64(123.01)), "123.01"}, - {interface{}("123.01"), "123.01"}, - {interface{}([]byte("123.01")), "123.01"}, - {interface{}(complex(1, 2)), "(1+2i)"}, + {any(nil), "null"}, + {any(true), "1"}, + {any(false), "0"}, + {any(123), "123"}, + {any(int8(-123)), "-123"}, + {any(int16(-123)), "-123"}, + {any(int32(-123)), "-123"}, + {any(int64(-123)), "-123"}, + {any(uint8(123)), "123"}, + {any(uint16(123)), "123"}, + {any(uint32(123)), "123"}, + {any(uint64(123)), "123"}, + {any(float32(123.01)), "123.01"}, + {any(float64(123.01)), "123.01"}, + {any("123.01"), "123.01"}, + {any([]byte("123.01")), "123.01"}, + {any(complex(1, 2)), "(1+2i)"}, } for _, tc := range testCases { s := ColumnValueString(tc.val) diff --git a/cdc/owner/barrier_test.go b/cdc/owner/barrier_test.go index ecaa347926..1bd2a200b6 100644 --- a/cdc/owner/barrier_test.go +++ b/cdc/owner/barrier_test.go @@ -56,7 +56,7 @@ func TestBarrierRandom(t *testing.T) { b.Update(barrierType(maxBarrierType), model.Ts(maxBarrierTs)) expectedBarriers[barrierType(maxBarrierType)] = model.Ts(maxBarrierTs) - for i := 0; i < 100000; i++ { + for range 100000 { switch rand.Intn(2) { case 0: tp := barrierType(rand.Intn(maxBarrierType)) diff --git a/cdc/owner/changefeed.go b/cdc/owner/changefeed.go index 950fa2fa27..026728d982 100755 --- a/cdc/owner/changefeed.go +++ b/cdc/owner/changefeed.go @@ -676,11 +676,9 @@ LOOP2: c.ddlSink.run(cancelCtx) c.ddlPuller = c.newDDLPuller(c.upstream, ddlStartTs, c.id, c.schema, filter) - c.wg.Add(1) - go func() { - defer c.wg.Done() + c.wg.Go(func() { c.Throw(ctx)(c.ddlPuller.Run(cancelCtx)) - }() + }) c.downstreamObserver, err = c.newDownstreamObserver(ctx, c.id, cfInfo.SinkURI, cfInfo.Config) if err != nil { @@ -690,20 +688,16 @@ LOOP2: c.redoDDLMgr = redo.NewDDLManager(c.id, cfInfo.Config.Consistent, ddlStartTs) if c.redoDDLMgr.Enabled() { - c.wg.Add(1) - go func() { - defer c.wg.Done() + c.wg.Go(func() { c.Throw(ctx)(c.redoDDLMgr.Run(cancelCtx)) - }() + }) } c.redoMetaMgr = redo.NewMetaManager(c.id, cfInfo.Config.Consistent, checkpointTs) if c.redoMetaMgr.Enabled() { - c.wg.Add(1) - go func() { - defer c.wg.Done() + c.wg.Go(func() { c.Throw(ctx)(c.redoMetaMgr.Run(cancelCtx)) - }() + }) log.Info("owner creates redo manager", zap.String("namespace", c.id.Namespace), zap.String("changefeed", c.id.ID)) diff --git a/cdc/owner/changefeed_test.go b/cdc/owner/changefeed_test.go index 4f8c40677a..206de1ca82 100644 --- a/cdc/owner/changefeed_test.go +++ b/cdc/owner/changefeed_test.go @@ -110,11 +110,9 @@ type mockDDLSink struct { } func (m *mockDDLSink) run(ctx context.Context) { - m.wg.Add(1) - go func() { + m.wg.Go(func() { <-ctx.Done() - m.wg.Done() - }() + }) } func (m *mockDDLSink) emitDDLEvent(_ context.Context, ddl *model.DDLEvent) (bool, error) { @@ -684,7 +682,7 @@ func testChangefeedReleaseResource( } func TestBarrierAdvance(t *testing.T) { - for i := 0; i < 2; i++ { + for i := range 2 { globalVars, changefeedInfo := vars.NewGlobalVarsAndChangefeedInfo4Test() ctx := context.Background() if i == 1 { diff --git a/cdc/owner/ddl_manager_test.go b/cdc/owner/ddl_manager_test.go index 3ff2f2c2e6..0fa4ee5adf 100644 --- a/cdc/owner/ddl_manager_test.go +++ b/cdc/owner/ddl_manager_test.go @@ -133,7 +133,7 @@ func TestBarriers(t *testing.T) { // test tableBarrier limit dm.pendingDDLs = make(map[model.TableName][]*model.DDLEvent) dm.ddlResolvedTs = 1024 - for i := 0; i < 512; i++ { + for i := range 512 { tableID := int64(i) tableName := model.TableName{Table: fmt.Sprintf("test_%d", i), TableID: tableID} dm.pendingDDLs[tableName] = append(dm.pendingDDLs[tableName], diff --git a/cdc/owner/owner.go b/cdc/owner/owner.go index 7c7307a714..d21647a55a 100644 --- a/cdc/owner/owner.go +++ b/cdc/owner/owner.go @@ -883,10 +883,10 @@ func (o *ownerImpl) updateGCSafepoint( // to prevent upstream TiDB GC from removing data that is still needed by TiCDC. // GcSafepoint is the minimum checkpointTs of all changefeeds that replicating a same upstream TiDB cluster. func (o *ownerImpl) calculateGCSafepoint(state *orchestrator.GlobalReactorState) ( - map[uint64]uint64, map[uint64]interface{}, + map[uint64]uint64, map[uint64]any, ) { minCheckpointTsMap := make(map[uint64]uint64) - forceUpdateMap := make(map[uint64]interface{}) + forceUpdateMap := make(map[uint64]any) for changefeedID, changefeedState := range state.Changefeeds { if changefeedState.Info == nil || !changefeedState.Info.NeedBlockGC() { diff --git a/cdc/owner/owner_test.go b/cdc/owner/owner_test.go index 23c9359ab5..4592c3285d 100644 --- a/cdc/owner/owner_test.go +++ b/cdc/owner/owner_test.go @@ -162,8 +162,7 @@ func createOwner4Test(globalVars *vars.GlobalVars, t *testing.T) (*ownerImpl, *o func TestCreateRemoveChangefeed(t *testing.T) { globalVars := vars.NewGlobalVars4Test() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() owner, state, tester := createOwner4Test(globalVars, t) @@ -680,8 +679,7 @@ func TestUpdateGCSafePoint(t *testing.T) { mockPDClient := &gc.MockPDClient{} m := upstream.NewManager4Test(mockPDClient) o := NewOwner(m, nil, vars.NewGlobalVars4Test()).(*ownerImpl) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() state := orchestrator.NewGlobalStateForTest(etcd.DefaultCDCClusterID) tester := orchestrator.NewReactorStateTester(t, state, nil) @@ -793,7 +791,7 @@ func TestUpdateGCSafePoint(t *testing.T) { func TestCalculateGCSafepointTs(t *testing.T) { state := orchestrator.NewGlobalStateForTest(etcd.DefaultCDCClusterID) expectMinTsMap := make(map[uint64]uint64) - expectForceUpdateMap := make(map[uint64]interface{}) + expectForceUpdateMap := make(map[uint64]any) o := &ownerImpl{changefeeds: make(map[model.ChangeFeedID]*changefeed)} o.upstreamManager = upstream.NewManager4Test(nil) @@ -802,7 +800,7 @@ func TestCalculateGCSafepointTs(t *testing.T) { model.StateWarning, model.StatePending, model.StateFailed, /* failed changefeed with normal error should not be ignored */ } - for i := 0; i < 100; i++ { + for i := range 100 { cfID := model.DefaultChangeFeedID(fmt.Sprintf("testChangefeed-%d", i)) upstreamID := uint64(i / 10) cfStatus := &model.ChangeFeedStatus{CheckpointTs: uint64(i) + 100} @@ -835,7 +833,7 @@ func TestCalculateGCSafepointTs(t *testing.T) { } } - for i := 0; i < 10; i++ { + for i := range 10 { cfID := model.DefaultChangeFeedID(fmt.Sprintf("testChangefeed-ignored-%d", i)) upstreamID := uint64(i) cfStatus := &model.ChangeFeedStatus{CheckpointTs: uint64(i)} @@ -863,7 +861,7 @@ func TestCalculateGCSafepointTs(t *testing.T) { func TestCalculateGCSafepointTsNoChangefeed(t *testing.T) { state := orchestrator.NewGlobalStateForTest(etcd.DefaultCDCClusterID) - expectForceUpdateMap := make(map[uint64]interface{}) + expectForceUpdateMap := make(map[uint64]any) o := &ownerImpl{changefeeds: make(map[model.ChangeFeedID]*changefeed)} o.upstreamManager = upstream.NewManager4Test(nil) up, err := o.upstreamManager.GetDefaultUpstream() @@ -914,8 +912,7 @@ func TestFixChangefeedState(t *testing.T) { func TestCheckClusterVersion(t *testing.T) { globalVars := vars.NewGlobalVars4Test() owner4Test, state, tester := createOwner4Test(globalVars, t) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() tester.MustUpdate(fmt.Sprintf("%s/capture/6bbc01c8-0605-4f86-a0f9-b3119109b225", etcd.DefaultClusterAndMetaPrefix), diff --git a/cdc/owner/status_provider.go b/cdc/owner/status_provider.go index 420e141a48..9542b43845 100644 --- a/cdc/owner/status_provider.go +++ b/cdc/owner/status_provider.go @@ -89,7 +89,7 @@ type Query struct { Tp QueryType ChangeFeedID model.ChangeFeedID - Data interface{} + Data any } // NewStatusProvider returns a new StatusProvider for the owner. diff --git a/cdc/processor/manager.go b/cdc/processor/manager.go index b9f76bd963..c79a3b1660 100644 --- a/cdc/processor/manager.go +++ b/cdc/processor/manager.go @@ -43,7 +43,7 @@ const ( type command struct { tp commandTp - payload interface{} + payload any done chan<- error } @@ -324,7 +324,7 @@ func (m *managerImpl) WriteDebugInfo( // sendCommands sends command to manager. // `done` is closed upon command completion or sendCommand returns error. func (m *managerImpl) sendCommand( - ctx context.Context, tp commandTp, payload interface{}, done chan<- error, + ctx context.Context, tp commandTp, payload any, done chan<- error, ) error { cmd := &command{tp: tp, payload: payload, done: done} select { diff --git a/cdc/processor/memquota/mem_quota.go b/cdc/processor/memquota/mem_quota.go index c30640037a..04eb6363af 100644 --- a/cdc/processor/memquota/mem_quota.go +++ b/cdc/processor/memquota/mem_quota.go @@ -210,7 +210,7 @@ func (m *MemQuota) Release(span tablepb.Span, resolved model.ResolvedTs) { return records[i].ResolvedTs.Greater(resolved) }) var toRelease uint64 = 0 - for j := 0; j < i; j++ { + for j := range i { toRelease += records[j].Size } m.tableMemory.ReplaceOrInsert(span, records[i:]) diff --git a/cdc/processor/memquota/mem_quota_test.go b/cdc/processor/memquota/mem_quota_test.go index 71ba469ec8..d46ecfd19c 100644 --- a/cdc/processor/memquota/mem_quota_test.go +++ b/cdc/processor/memquota/mem_quota_test.go @@ -59,18 +59,14 @@ func TestMemQuotaBlockAcquire(t *testing.T) { m.Record(span, model.NewResolvedTs(2), 50) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := m.BlockAcquire(50) require.NoError(t, err) - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { err := m.BlockAcquire(50) require.NoError(t, err) - }() + }) m.Release(span, model.NewResolvedTs(1)) m.Release(span, model.NewResolvedTs(2)) wg.Wait() @@ -87,37 +83,29 @@ func TestMemQuotaClose(t *testing.T) { m.Record(span, model.NewResolvedTs(2), 100) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := m.BlockAcquire(50) if err != nil { require.ErrorIs(t, err, context.Canceled) } - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { err := m.BlockAcquire(50) if err != nil { require.ErrorIs(t, err, context.Canceled) } - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { err := m.BlockAcquire(50) if err != nil { require.ErrorIs(t, err, context.Canceled) } - }() + }) // Randomly release some memory. - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { m.Release(span, model.NewResolvedTs(2)) - }() + }) m.Close() wg.Wait() } @@ -136,12 +124,10 @@ func TestMemQuotaRefund(t *testing.T) { // Test notify the blocked acquire. var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := m.BlockAcquire(50) require.NoError(t, err) - }() + }) m.Refund(50) wg.Wait() } diff --git a/cdc/processor/processor.go b/cdc/processor/processor.go index fbf015e6b4..001d77462d 100644 --- a/cdc/processor/processor.go +++ b/cdc/processor/processor.go @@ -1023,9 +1023,7 @@ func (c *component[R]) spawn(ctx context.Context) { c.warnings = make(chan error, 16) changefeedID := c.changefeedID - c.wg.Add(1) - go func() { - defer c.wg.Done() + c.wg.Go(func() { err := c.r.Run(c.ctx, c.warnings) if err != nil && errors.Cause(err) != context.Canceled { log.Error("processor sub-component fails", @@ -1038,7 +1036,7 @@ func (c *component[R]) spawn(ctx context.Context) { case c.errors <- err: } } - }() + }) c.r.WaitForReady(ctx) log.Info("processor sub-component starts", zap.String("namespace", changefeedID.Namespace), diff --git a/cdc/processor/sinkmanager/manager.go b/cdc/processor/sinkmanager/manager.go index 171443fa1b..7c384efac5 100644 --- a/cdc/processor/sinkmanager/manager.go +++ b/cdc/processor/sinkmanager/manager.go @@ -219,9 +219,7 @@ func (m *SinkManager) Run(ctx context.Context, warnings ...chan<- error) (err er m.sinkEg, sinkCtx = errgroup.WithContext(m.managerCtx) m.startSinkWorkers(sinkCtx, m.sinkEg, splitTxn) m.sinkEg.Go(func() error { return m.generateSinkTasks(sinkCtx) }) - m.wg.Add(1) - go func() { - defer m.wg.Done() + m.wg.Go(func() { if err := m.sinkEg.Wait(); err != nil && !cerror.Is(err, context.Canceled) { log.Error("Worker handles or generates sink task failed", zap.String("namespace", m.changefeedID.Namespace), @@ -232,16 +230,14 @@ func (m *SinkManager) Run(ctx context.Context, warnings ...chan<- error) (err er case <-m.managerCtx.Done(): } } - }() + }) } if m.redoDMLMgr != nil && m.redoEg == nil { var redoCtx context.Context m.redoEg, redoCtx = errgroup.WithContext(m.managerCtx) m.startRedoWorkers(redoCtx, m.redoEg) m.redoEg.Go(func() error { return m.generateRedoTasks(redoCtx) }) - m.wg.Add(1) - go func() { - defer m.wg.Done() + m.wg.Go(func() { if err := m.redoEg.Wait(); err != nil && !cerror.Is(err, context.Canceled) { log.Error("Worker handles or generates redo task failed", zap.String("namespace", m.changefeedID.Namespace), @@ -252,7 +248,7 @@ func (m *SinkManager) Run(ctx context.Context, warnings ...chan<- error) (err er case <-m.managerCtx.Done(): } } - }() + }) } close(m.ready) @@ -287,7 +283,7 @@ func (m *SinkManager) Run(ctx context.Context, warnings ...chan<- error) (err er log.Info("Sink manager is closing all table sinks", zap.String("namespace", m.changefeedID.Namespace), zap.String("changefeed", m.changefeedID.ID)) - m.tableSinks.Range(func(span tablepb.Span, value interface{}) bool { + m.tableSinks.Range(func(span tablepb.Span, value any) bool { value.(*tableSinkWrapper).closeTableSink() m.sinkMemQuota.ClearTable(span) return true @@ -397,7 +393,7 @@ func (m *SinkManager) clearSinkFactory() { } func (m *SinkManager) startSinkWorkers(ctx context.Context, eg *errgroup.Group, splitTxn bool) { - for i := 0; i < sinkWorkerNum; i++ { + for range sinkWorkerNum { w := newSinkWorker(m.changefeedID, m.sourceManager, m.sinkMemQuota, splitTxn) m.sinkWorkers = append(m.sinkWorkers, w) @@ -406,7 +402,7 @@ func (m *SinkManager) startSinkWorkers(ctx context.Context, eg *errgroup.Group, } func (m *SinkManager) startRedoWorkers(ctx context.Context, eg *errgroup.Group) { - for i := 0; i < redoWorkerNum; i++ { + for range redoWorkerNum { w := newRedoWorker(m.changefeedID, m.sourceManager, m.redoMemQuota, m.redoDMLMgr) m.redoWorkers = append(m.redoWorkers, w) @@ -417,9 +413,7 @@ func (m *SinkManager) startRedoWorkers(ctx context.Context, eg *errgroup.Group) // backgroundGC is used to clean up the old data in the sorter. func (m *SinkManager) backgroundGC(errors chan<- error) { ticker := time.NewTicker(time.Second) - m.wg.Add(1) - go func() { - defer m.wg.Done() + m.wg.Go(func() { defer ticker.Stop() for { select { @@ -473,7 +467,7 @@ func (m *SinkManager) backgroundGC(errors chan<- error) { }) } } - }() + }) } func (m *SinkManager) getUpperBound(tableSinkUpperBoundTs model.Ts) sorter.Position { @@ -810,7 +804,7 @@ func (m *SinkManager) UpdateReceivedSorterResolvedTs(span tablepb.Span, ts model // UpdateBarrierTs update all tableSink's barrierTs in the SinkManager func (m *SinkManager) UpdateBarrierTs(globalBarrierTs model.Ts, tableBarrier map[model.TableID]model.Ts) { - m.tableSinks.Range(func(span tablepb.Span, value interface{}) bool { + m.tableSinks.Range(func(span tablepb.Span, value any) bool { barrierTs := globalBarrierTs if tableBarrierTs, ok := tableBarrier[span.TableID]; ok && tableBarrierTs < globalBarrierTs { barrierTs = tableBarrierTs @@ -943,7 +937,7 @@ func (m *SinkManager) RemoveTable(span tablepb.Span) { // GetAllCurrentTableSpans returns all spans in the sinkManager. func (m *SinkManager) GetAllCurrentTableSpans() []tablepb.Span { var spans []tablepb.Span - m.tableSinks.Range(func(key tablepb.Span, value interface{}) bool { + m.tableSinks.Range(func(key tablepb.Span, value any) bool { spans = append(spans, key) return true }) @@ -953,7 +947,7 @@ func (m *SinkManager) GetAllCurrentTableSpans() []tablepb.Span { // GetAllCurrentTableSpansCount returns the table spans count in the sinkManager. func (m *SinkManager) GetAllCurrentTableSpansCount() int { res := 0 - m.tableSinks.Range(func(key tablepb.Span, value interface{}) bool { + m.tableSinks.Range(func(key tablepb.Span, value any) bool { res++ return true }) diff --git a/cdc/processor/sinkmanager/redo_log_advancer_test.go b/cdc/processor/sinkmanager/redo_log_advancer_test.go index 31b4e5a664..362ecb5999 100644 --- a/cdc/processor/sinkmanager/redo_log_advancer_test.go +++ b/cdc/processor/sinkmanager/redo_log_advancer_test.go @@ -175,7 +175,7 @@ func (suite *redoLogAdvancerSuite) TestHasEnoughMem() { advancer := newRedoLogAdvancer(task, memoryQuota, 512, manager) require.NotNil(suite.T(), advancer) require.True(suite.T(), advancer.hasEnoughMem()) - for i := 0; i < 6; i++ { + for range 6 { // 6 * 256 = 1536 > 1024 advancer.appendEvents([]*model.RowChangedEvent{{}}, 256) } @@ -204,7 +204,7 @@ func (suite *redoLogAdvancerSuite) TestAppendEvents() { advancer := newRedoLogAdvancer(task, memoryQuota, 512, manager) require.NotNil(suite.T(), advancer) require.True(suite.T(), advancer.hasEnoughMem()) - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{{}}, 256) } require.Equal(suite.T(), uint64(512), advancer.pendingTxnSize) @@ -234,7 +234,7 @@ func (suite *redoLogAdvancerSuite) TestTryMoveMoveToNextTxn() { require.Equal(suite.T(), uint64(1), advancer.currTxnCommitTs) // Append 2 events with commit ts 2 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 2}, }, 256) @@ -277,7 +277,7 @@ func (suite *redoLogAdvancerSuite) TestAdvance() { advancer.tryMoveToNextTxn(1, pos) // 2. append 2 events with commit ts 2 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 2}, }, 256) @@ -315,7 +315,7 @@ func (suite *redoLogAdvancerSuite) TestTryAdvanceWhenExceedAvailableMem() { advancer.tryMoveToNextTxn(2, pos) // 2. append 3 events with commit ts 3 - for i := 0; i < 3; i++ { + for range 3 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -363,7 +363,7 @@ func (suite *redoLogAdvancerSuite) TestTryAdvanceWhenReachTheMaxUpdateIntSizeAnd advancer.tryMoveToNextTxn(2, pos) // 2. append 2 events with commit ts 3 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -405,7 +405,7 @@ func (suite *redoLogAdvancerSuite) TestFinish() { advancer.tryMoveToNextTxn(2, pos) // 2. append 2 events with commit ts 3 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -454,7 +454,7 @@ func (suite *redoLogAdvancerSuite) TestTryAdvanceAndBlockAcquireWithSplitTxn() { advancer.tryMoveToNextTxn(2, pos) // 2. append 3 events with commit ts 3, this will exceed the memory quota. - for i := 0; i < 3; i++ { + for range 3 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) diff --git a/cdc/processor/sinkmanager/redo_log_worker_test.go b/cdc/processor/sinkmanager/redo_log_worker_test.go index 14ca37b25b..faffc5dddd 100644 --- a/cdc/processor/sinkmanager/redo_log_worker_test.go +++ b/cdc/processor/sinkmanager/redo_log_worker_test.go @@ -107,12 +107,10 @@ func (suite *redoLogWorkerSuite) TestHandleTaskGotSomeFilteredEvents() { taskChan := make(chan *redoTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) callback := func(lastWritePos sorter.Position) { require.Equal(suite.T(), sorter.Position{ @@ -156,12 +154,10 @@ func (suite *redoLogWorkerSuite) TestHandleTaskAbortWhenNoMemAndOneTxnFinished() taskChan := make(chan *redoTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) callback := func(lastWritePos sorter.Position) { require.Equal(suite.T(), sorter.Position{ @@ -203,12 +199,10 @@ func (suite *redoLogWorkerSuite) TestHandleTaskAbortWhenNoMemAndBlocked() { taskChan := make(chan *redoTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.ErrorIs(suite.T(), err, context.Canceled) - }() + }) callback := func(lastWritePos sorter.Position) { require.Equal(suite.T(), sorter.Position{ @@ -248,12 +242,10 @@ func (suite *redoLogWorkerSuite) TestHandleTaskWithSplitTxnAndAdvanceIfNoWorkloa taskChan := make(chan *redoTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.ErrorIs(suite.T(), err, context.Canceled) - }() + }) callback := func(lastWritePos sorter.Position) { require.Equal(suite.T(), sorter.Position{ @@ -296,12 +288,10 @@ func (suite *redoLogWorkerSuite) TestHandleTaskWithoutMemory() { taskChan := make(chan *redoTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) defer sink.Close() diff --git a/cdc/processor/sinkmanager/table_sink_advancer_test.go b/cdc/processor/sinkmanager/table_sink_advancer_test.go index f66f4a1e38..05853b67eb 100644 --- a/cdc/processor/sinkmanager/table_sink_advancer_test.go +++ b/cdc/processor/sinkmanager/table_sink_advancer_test.go @@ -171,7 +171,7 @@ func (suite *tableSinkAdvancerSuite) TestHasEnoughMem() { advancer := newTableSinkAdvancer(task, true, memoryQuota, 512) require.NotNil(suite.T(), advancer) require.True(suite.T(), advancer.hasEnoughMem()) - for i := 0; i < 6; i++ { + for range 6 { // 6 * 256 = 1536 > 1024 advancer.appendEvents([]*model.RowChangedEvent{{}}, 256) } @@ -200,7 +200,7 @@ func (suite *tableSinkAdvancerSuite) TestAppendEvents() { advancer := newTableSinkAdvancer(task, true, memoryQuota, 512) require.NotNil(suite.T(), advancer) require.True(suite.T(), advancer.hasEnoughMem()) - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{{}}, 256) } require.Equal(suite.T(), uint64(512), advancer.pendingTxnSize) @@ -234,7 +234,7 @@ func (suite *tableSinkAdvancerSuite) TestTryMoveMoveToNextTxn() { require.Equal(suite.T(), uint64(1), advancer.currTxnCommitTs) // Append 2 events with commit ts 2 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 2}, }, 256) @@ -271,7 +271,7 @@ func (suite *tableSinkAdvancerSuite) TestAdvanceTheSameCommitTsEventsWithCommitF advancer.tryMoveToNextTxn(1) // 2. append 2 events with commit ts 2 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 2}, }, 256) @@ -315,7 +315,7 @@ func (suite *tableSinkAdvancerSuite) TestAdvanceTheSameCommitTsEventsWithoutComm advancer.tryMoveToNextTxn(1) // 2. append 2 events with commit ts 3 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -370,7 +370,7 @@ func (suite *tableSinkAdvancerSuite) TestAdvanceDifferentCommitTsEventsWithSplit } // 3. append 2 events with commit ts 3 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -528,7 +528,7 @@ func (suite *tableSinkAdvancerSuite) TestTryAdvanceWhenExceedAvailableMem() { advancer.tryMoveToNextTxn(2) // 2. append 3 events with commit ts 3 - for i := 0; i < 3; i++ { + for range 3 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -583,7 +583,7 @@ func (suite *tableSinkAdvancerSuite) TestTryAdvanceWhenReachTheMaxUpdateIntSizeA advancer.tryMoveToNextTxn(2) // 2. append 2 events with commit ts 3 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -633,7 +633,7 @@ func (suite *tableSinkAdvancerSuite) TestFinish() { advancer.tryMoveToNextTxn(2) // 2. append 2 events with commit ts 3 - for i := 0; i < 2; i++ { + for range 2 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -686,7 +686,7 @@ func (suite *tableSinkAdvancerSuite) TestTryAdvanceAndForceAcquireWithoutSplitTx advancer.tryMoveToNextTxn(2) // 2. append 3 events with commit ts 3, this will exceed the memory quota. - for i := 0; i < 3; i++ { + for range 3 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -736,7 +736,7 @@ func (suite *tableSinkAdvancerSuite) TestTryAdvanceAndBlockAcquireWithSplitTxn() advancer.tryMoveToNextTxn(2) // 2. append 3 events with commit ts 3, this will exceed the memory quota. - for i := 0; i < 3; i++ { + for range 3 { advancer.appendEvents([]*model.RowChangedEvent{ {CommitTs: 3}, }, 256) @@ -762,8 +762,7 @@ func (suite *tableSinkAdvancerSuite) TestTryAdvanceAndBlockAcquireWithSplitTxn() }() var wg sync.WaitGroup - wg.Add(1) - go func() { + wg.Go(func() { // Wait all events are flushed. require.Eventually(suite.T(), func() bool { return len(sink.GetEvents()) == 4 @@ -780,7 +779,6 @@ func (suite *tableSinkAdvancerSuite) TestTryAdvanceAndBlockAcquireWithSplitTxn() }, 5*time.Second, 10*time.Millisecond) require.Equal(suite.T(), uint64(0), advancer.committedTxnSize) require.Equal(suite.T(), uint64(0), advancer.pendingTxnSize) - wg.Done() - }() + }) wg.Wait() } diff --git a/cdc/processor/sinkmanager/table_sink_worker_test.go b/cdc/processor/sinkmanager/table_sink_worker_test.go index f1dcfaed25..18d8fc4b26 100644 --- a/cdc/processor/sinkmanager/table_sink_worker_test.go +++ b/cdc/processor/sinkmanager/table_sink_worker_test.go @@ -191,12 +191,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithSplitTxnAndGotSomeFilteredE taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -242,12 +240,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithSplitTxnAndAbortWhenNoMemAn taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -292,12 +288,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithSplitTxnAndAbortWhenNoMemAn taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.ErrorIs(suite.T(), err, context.Canceled) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -345,12 +339,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithSplitTxnAndOnlyAdvanceWhenR taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.ErrorIs(suite.T(), err, context.Canceled) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -400,12 +392,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithoutSplitTxnAndAbortWhenNoMe taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -453,12 +443,10 @@ func (suite *tableSinkWorkerSuite) TestTaskWithoutSplitTxnOnlyAdvanceWhenReachMa taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -502,12 +490,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithSplitTxnAndAdvanceTableWhen taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.ErrorIs(suite.T(), err, context.Canceled) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -555,12 +541,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithSplitTxnAndAdvanceTableIfNo taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.ErrorIs(suite.T(), err, context.Canceled) - }() + }) wrapper, _ := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -605,12 +589,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskUseDifferentBatchIDEveryTime() taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) callback := func(lastWritePos sorter.Position) { @@ -684,12 +666,10 @@ func (suite *tableSinkWorkerSuite) TestHandleTaskWithoutMemory() { taskChan := make(chan *sinkTask) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := w.handleTasks(ctx, taskChan) require.Equal(suite.T(), context.Canceled, err) - }() + }) wrapper, sink := createTableSinkWrapper(suite.testChangefeedID, suite.testSpan) defer sink.Close() diff --git a/cdc/processor/sourcemanager/sorter/factory/pebble.go b/cdc/processor/sourcemanager/sorter/factory/pebble.go index 3b4ff1ad07..b800ac5fde 100644 --- a/cdc/processor/sourcemanager/sorter/factory/pebble.go +++ b/cdc/processor/sourcemanager/sorter/factory/pebble.go @@ -92,12 +92,12 @@ type pebbleLogger struct{ id int } var _ pebble.Logger = (*pebbleLogger)(nil) -func (logger *pebbleLogger) Infof(format string, args ...interface{}) { +func (logger *pebbleLogger) Infof(format string, args ...any) { // Do not output low-level pebble log to TiCDC log. log.Debug(fmt.Sprintf(format, args...), zap.Int("db", logger.id)) } -func (logger *pebbleLogger) Fatalf(format string, args ...interface{}) { +func (logger *pebbleLogger) Fatalf(format string, args ...any) { log.Panic(fmt.Sprintf(format, args...), zap.Int("db", logger.id)) } diff --git a/cdc/processor/sourcemanager/sorter/mounted_iter_test.go b/cdc/processor/sourcemanager/sorter/mounted_iter_test.go index 0a690597b0..d93832dfc9 100644 --- a/cdc/processor/sourcemanager/sorter/mounted_iter_test.go +++ b/cdc/processor/sourcemanager/sorter/mounted_iter_test.go @@ -63,7 +63,7 @@ func TestMountedEventIter(t *testing.T) { defer quota.Close() iter := NewMountedEventIter(model.ChangeFeedID{}, rawIter, mg, 3, quota) - for i := 0; i < 3; i++ { + for i := range 3 { event, _, err := iter.Next(context.Background()) require.NotNil(t, event) require.Nil(t, err) diff --git a/cdc/processor/sourcemanager/sorter/pebble/event_sorter.go b/cdc/processor/sourcemanager/sorter/pebble/event_sorter.go index 12917dc102..49c0186cd9 100644 --- a/cdc/processor/sourcemanager/sorter/pebble/event_sorter.go +++ b/cdc/processor/sourcemanager/sorter/pebble/event_sorter.go @@ -71,7 +71,7 @@ type EventIter struct { // New creates an EventSorter instance. func New(ID model.ChangeFeedID, dbs []*pebble.DB) *EventSorter { channs := make([]*chann.DrainableChann[eventWithTableID], 0, len(dbs)) - for i := 0; i < len(dbs); i++ { + for range dbs { channs = append(channs, chann.NewAutoDrainChann[eventWithTableID](chann.Cap(128))) } diff --git a/cdc/puller/ddl_puller_test.go b/cdc/puller/ddl_puller_test.go index c5f1fb8dad..656ebe8689 100644 --- a/cdc/puller/ddl_puller_test.go +++ b/cdc/puller/ddl_puller_test.go @@ -143,8 +143,7 @@ func TestHandleRenameTable(t *testing.T) { require.NoError(t, err) ddlJobPullerImpl.filter = f - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() go ddlJobPuller.Run(ctx) go func() { @@ -559,12 +558,10 @@ func TestDDLPuller(t *testing.T) { ddlJobPullerImpl.setResolvedTs(startTs) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := p.Run(ctx) require.True(t, errors.ErrorEqual(err, context.Canceled)) - }() + }) defer wg.Wait() defer p.Close() @@ -690,15 +687,13 @@ func TestResolvedTsStuck(t *testing.T) { ddlJobPullerImpl.setResolvedTs(startTs) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := p.Run(ctx) if errors.Cause(err) == context.Canceled { err = nil } require.Nil(t, err) - }() + }) defer wg.Wait() defer p.Close() diff --git a/cdc/puller/frontier/frontier_bench_test.go b/cdc/puller/frontier/frontier_bench_test.go index 50e6c30f60..c994e747a7 100644 --- a/cdc/puller/frontier/frontier_bench_test.go +++ b/cdc/puller/frontier/frontier_bench_test.go @@ -41,7 +41,7 @@ func BenchmarkSpanFrontier(b *testing.B) { b.Run(test.name, func(b *testing.B) { spans := make([]tablepb.Span, 0, n) - for i := 0; i < n; i++ { + for i := range n { span := tablepb.Span{ StartKey: toCMPBytes(i), EndKey: toCMPBytes(i + 1), @@ -80,7 +80,7 @@ func BenchmarkSpanFrontierOverlap(b *testing.B) { b.Run(fmt.Sprintf("%s_%d", test.name, step), func(b *testing.B) { spans := make([]tablepb.Span, 0, n) forward := make([]tablepb.Span, 0, n) - for i := 0; i < n; i++ { + for i := range n { spans = append(spans, tablepb.Span{ StartKey: toCMPBytes(i), EndKey: toCMPBytes(i + 1), diff --git a/cdc/puller/frontier/frontier_test.go b/cdc/puller/frontier/frontier_test.go index deaad780c9..e45ffbab9b 100644 --- a/cdc/puller/frontier/frontier_test.go +++ b/cdc/puller/frontier/frontier_test.go @@ -19,7 +19,7 @@ import ( "fmt" "math" "math/rand" - "sort" + "slices" "testing" "github.com/pingcap/tiflow/cdc/kv/regionlock" @@ -383,8 +383,8 @@ func checkFrontier(t *testing.T, f Frontier) { return true }) require.Equal(t, len(tsInHeap), len(tsInList)) - sort.Slice(tsInList, func(i, j int) bool { return tsInList[i] < tsInList[j] }) - sort.Slice(tsInHeap, func(i, j int) bool { return tsInHeap[i] < tsInHeap[j] }) + slices.Sort(tsInList) + slices.Sort(tsInHeap) require.Equal(t, tsInHeap, tsInList) require.Equal(t, tsInList[0], f.Frontier()) } @@ -507,7 +507,7 @@ func TestRandomMergeAndSplit(t *testing.T) { frontier.Forward(1, tablepb.Span{StartKey: start, EndKey: end}, nextTs) require.Equal(t, nextTs, frontier.Frontier()) - for i := 0; i < 5000; i++ { + for range 5000 { totalLockedRanges := rangelock.Len() unchangedRegions := make([]lockedRegion, 0, totalLockedRanges) diff --git a/cdc/puller/frontier/heap_test.go b/cdc/puller/frontier/heap_test.go index b0c153661f..1bcdbf2129 100644 --- a/cdc/puller/frontier/heap_test.go +++ b/cdc/puller/frontier/heap_test.go @@ -27,7 +27,7 @@ func TestInsert(t *testing.T) { var heap fibonacciHeap target := uint64(15000) - for i := 0; i < 5000; i++ { + for range 5000 { heap.Insert(uint64(10001) + target + 1) } heap.Insert(target) diff --git a/cdc/puller/frontier/list.go b/cdc/puller/frontier/list.go index cf8984ce06..0420463b6a 100644 --- a/cdc/puller/frontier/list.go +++ b/cdc/puller/frontier/list.go @@ -145,7 +145,7 @@ func (l *skipList) InsertNextToNode(seekR seekResult, key []byte, value *fibonac nexts: make([]*skipListNode, height), } - for level := 0; level < height; level++ { + for level := range height { prev := seekR[level] if prev == nil { prev = &l.head diff --git a/cdc/puller/frontier/list_test.go b/cdc/puller/frontier/list_test.go index 39dfb996c5..b0e757f471 100644 --- a/cdc/puller/frontier/list_test.go +++ b/cdc/puller/frontier/list_test.go @@ -31,7 +31,7 @@ func TestInsertAndRemove(t *testing.T) { t.Parallel() list := newSpanList() var keys [][]byte - for i := 0; i < 100000; i++ { + for range 100000 { key := make([]byte, rand.Intn(128)+1) rand.Read(key) keys = append(keys, key) @@ -46,7 +46,7 @@ func TestInsertAndRemove(t *testing.T) { } checkList(t, list) - for i := 0; i < 10000; i++ { + for range 10000 { indexToRemove := rand.Intn(10000) seekRes := list.Seek(keys[indexToRemove], make(seekResult, maxHeight)) if seekRes.Node().Next() == nil { diff --git a/cdc/puller/memorysorter/entry_sorter_test.go b/cdc/puller/memorysorter/entry_sorter_test.go index 08c354302c..cd01c45c1f 100644 --- a/cdc/puller/memorysorter/entry_sorter_test.go +++ b/cdc/puller/memorysorter/entry_sorter_test.go @@ -104,12 +104,10 @@ func TestEntrySorter(t *testing.T) { es := NewEntrySorter(model.GenerateChangeFeedID("test", "test-cf")) ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := es.Run(ctx) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) for _, tc := range testCases { for _, entry := range tc.input { es.AddEntry(ctx, model.NewPolymorphicEvent(entry)) @@ -130,17 +128,13 @@ func TestEntrySorterRandomly(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := es.Run(ctx) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) maxTs := uint64(1000000) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for resolvedTs := uint64(1); resolvedTs <= maxTs; resolvedTs += 400 { var opType model.OpType if rand.Intn(2) == 0 { @@ -148,7 +142,7 @@ func TestEntrySorterRandomly(t *testing.T) { } else { opType = model.OpTypeDelete } - for i := 0; i < 1000; i++ { + for range 1000 { entry := &model.RawKVEntry{ CRTs: uint64(int64(resolvedTs) + rand.Int63n(int64(maxTs-resolvedTs))), OpType: opType, @@ -158,7 +152,7 @@ func TestEntrySorterRandomly(t *testing.T) { es.AddEntry(ctx, model.NewResolvedPolymorphicEvent(0, resolvedTs)) } es.AddEntry(ctx, model.NewResolvedPolymorphicEvent(0, maxTs)) - }() + }) var lastTs uint64 var resolvedTs uint64 lastOpType := model.OpTypePut @@ -361,20 +355,16 @@ func BenchmarkSorter(b *testing.B) { es := NewEntrySorter(model.GenerateChangeFeedID("test", "test-cf")) ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := es.Run(ctx) if errors.Cause(err) != context.Canceled { panic(errors.Annotate(err, "unexpected error")) } - }() + }) maxTs := uint64(10000000) b.ResetTimer() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for resolvedTs := uint64(1); resolvedTs <= maxTs; resolvedTs += 400 { var opType model.OpType if rand.Intn(2) == 0 { @@ -382,7 +372,7 @@ func BenchmarkSorter(b *testing.B) { } else { opType = model.OpTypeDelete } - for i := 0; i < 100000; i++ { + for range 100000 { entry := &model.RawKVEntry{ CRTs: uint64(int64(resolvedTs) + rand.Int63n(1000)), OpType: opType, @@ -392,7 +382,7 @@ func BenchmarkSorter(b *testing.B) { es.AddEntry(ctx, model.NewResolvedPolymorphicEvent(0, resolvedTs)) } es.AddEntry(ctx, model.NewResolvedPolymorphicEvent(0, maxTs)) - }() + }) var resolvedTs uint64 for entry := range es.Output() { if entry.IsResolved() { diff --git a/cdc/puller/multiplexing_puller.go b/cdc/puller/multiplexing_puller.go index c6ee56d074..f0d5954feb 100644 --- a/cdc/puller/multiplexing_puller.go +++ b/cdc/puller/multiplexing_puller.go @@ -194,7 +194,7 @@ func NewMultiplexingPuller( mpuller.subscriptions.n = spanz.NewHashMap[subscription]() mpuller.inputChs = make([]chan kv.MultiplexingEvent, 0, workerCount) - for i := 0; i < workerCount; i++ { + for range workerCount { mpuller.inputChs = append(mpuller.inputChs, make(chan kv.MultiplexingEvent, inputChSize)) } return mpuller @@ -449,7 +449,7 @@ func (p *MultiplexingPuller) runResolvedTsAdvancer(ctx context.Context) error { var event kv.MultiplexingEvent var spans *model.ResolvedSpans - for i := 0; i < 128; i++ { + for range 128 { select { case <-ctx.Done(): return ctx.Err() diff --git a/cdc/puller/multiplexing_puller_test.go b/cdc/puller/multiplexing_puller_test.go index 6563c0f350..e6199f5bd5 100644 --- a/cdc/puller/multiplexing_puller_test.go +++ b/cdc/puller/multiplexing_puller_test.go @@ -55,11 +55,9 @@ func TestMultiplexingPullerResolvedForward(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { puller.run(ctx, false) - }() + }) events := []model.RegionFeedEvent{ { diff --git a/cdc/redo/manager.go b/cdc/redo/manager.go index c490751b69..c340032476 100644 --- a/cdc/redo/manager.go +++ b/cdc/redo/manager.go @@ -385,13 +385,10 @@ func (m *logManager) RemoveTable(span tablepb.Span) { func (m *logManager) prepareForFlush() *spanz.HashMap[model.Ts] { tableRtsMap := spanz.NewHashMap[model.Ts]() - m.rtsMap.Range(func(span tablepb.Span, value interface{}) bool { + m.rtsMap.Range(func(span tablepb.Span, value any) bool { rts := value.(*statefulRts) unflushed := rts.getUnflushed() - flushed := rts.getFlushed() - if unflushed > flushed { - flushed = unflushed - } + flushed := max(unflushed, rts.getFlushed()) tableRtsMap.ReplaceOrInsert(span, flushed) return true }) diff --git a/cdc/redo/manager_test.go b/cdc/redo/manager_test.go index d1302da01c..6a35e467ac 100644 --- a/cdc/redo/manager_test.go +++ b/cdc/redo/manager_test.go @@ -114,8 +114,7 @@ func TestConsistentConfig(t *testing.T) { // TestLogManagerInProcessor tests how redo log manager is used in processor. func TestLogManagerInProcessor(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() testWriteDMLs := func(storage string, useFileBackend bool) { ctx, cancel := context.WithCancel(ctx) @@ -227,8 +226,7 @@ func TestLogManagerInProcessor(t *testing.T) { // where the redo log manager needs to handle DDL event only. func TestLogManagerInOwner(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() testWriteDDLs := func(storage string, useFileBackend bool) { ctx, cancel := context.WithCancel(ctx) @@ -358,7 +356,7 @@ func runBenchTest(b *testing.B, storage string, useFileBackend bool) { tables := make([]model.TableID, 0, numOfTables) maxTsMap := spanz.NewHashMap[*model.Ts]() startTs := uint64(100) - for i := 0; i < numOfTables; i++ { + for i := range numOfTables { tableID := model.TableID(i) tables = append(tables, tableID) span := spanz.TableIDToComparableSpan(tableID) @@ -380,7 +378,7 @@ func runBenchTest(b *testing.B, storage string, useFileBackend bool) { defer wg.Done() maxCommitTs := maxTsMap.GetV(span) var rows []*model.RowChangedEvent - for i := 0; i < maxRowCount; i++ { + for i := range maxRowCount { if i%100 == 0 { // prepare new row change events b.StopTimer() diff --git a/cdc/redo/meta_manager_test.go b/cdc/redo/meta_manager_test.go index 3def675e38..ec6f1ac502 100644 --- a/cdc/redo/meta_manager_test.go +++ b/cdc/redo/meta_manager_test.go @@ -63,7 +63,7 @@ func TestInitAndWriteMeta(t *testing.T) { var notRemoveFiles []string require.NoError(t, err) - for i := 0; i < 10; i++ { + for i := range 10 { fileName := "dummy" + getChangefeedMatcher(changefeedID) + strconv.Itoa(i) err = extStorage.WriteFile(ctx, fileName, []byte{}) require.NoError(t, err) @@ -144,7 +144,7 @@ func TestPreCleanupAndWriteMeta(t *testing.T) { // write delete mark to simulate a deleted changefeed err = extStorage.WriteFile(ctx, getDeletedChangefeedMarker(changefeedID), []byte{}) require.NoError(t, err) - for i := 0; i < 10; i++ { + for i := range 10 { fileName := "dummy" + getChangefeedMatcher(changefeedID) + strconv.Itoa(i) err = extStorage.WriteFile(ctx, fileName, []byte{}) require.NoError(t, err) @@ -319,8 +319,7 @@ func TestGCAndCleanup(t *testing.T) { cancel() require.ErrorIs(t, eg.Wait(), context.Canceled) - cleanupCtx, cleanupCancel := context.WithCancel(context.Background()) - defer cleanupCancel() + cleanupCtx := t.Context() m.Cleanup(cleanupCtx) ret, err := extStorage.FileExists(cleanupCtx, getDeletedChangefeedMarker(changefeedID)) require.NoError(t, err) diff --git a/cdc/redo/reader/file.go b/cdc/redo/reader/file.go index b3fffb1a05..2312fd299e 100644 --- a/cdc/redo/reader/file.go +++ b/cdc/redo/reader/file.go @@ -390,10 +390,7 @@ func (r *reader) isTornEntry(data []byte) bool { chunks := [][]byte{} // split data on sector boundaries for curOff < len(data) { - chunkLen := int(redo.MinSectorSize - (fileOff % redo.MinSectorSize)) - if chunkLen > len(data)-curOff { - chunkLen = len(data) - curOff - } + chunkLen := min(int(redo.MinSectorSize-(fileOff%redo.MinSectorSize)), len(data)-curOff) chunks = append(chunks, data[curOff:curOff+chunkLen]) fileOff += int64(chunkLen) curOff += chunkLen diff --git a/cdc/redo/reader/file_test.go b/cdc/redo/reader/file_test.go index 02a4d96cd0..7ef46381e4 100644 --- a/cdc/redo/reader/file_test.go +++ b/cdc/redo/reader/file_test.go @@ -37,8 +37,7 @@ func TestReaderNewReader(t *testing.T) { func TestFileReaderRead(t *testing.T) { dir := t.TempDir() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() uri, err := url.Parse(fmt.Sprintf("file://%s", dir)) require.NoError(t, err) diff --git a/cdc/redo/reader/reader.go b/cdc/redo/reader/reader.go index 0bdd10a0ac..ec9b26a7d6 100644 --- a/cdc/redo/reader/reader.go +++ b/cdc/redo/reader/reader.go @@ -325,7 +325,7 @@ type logHeap []*logWithIdx func newLogHeap(fileReaders []fileReader) (logHeap, error) { h := logHeap{} - for i := 0; i < len(fileReaders); i++ { + for i := range fileReaders { rl, err := fileReaders[i].Read() if err != nil { if err != io.EOF { @@ -387,11 +387,11 @@ func (h logHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h *logHeap) Push(x interface{}) { +func (h *logHeap) Push(x any) { *h = append(*h, x.(*logWithIdx)) } -func (h *logHeap) Pop() interface{} { +func (h *logHeap) Pop() any { old := *h n := len(old) x := old[n-1] diff --git a/cdc/redo/writer/file/file_test.go b/cdc/redo/writer/file/file_test.go index b218a4fa9e..19d36ab90a 100644 --- a/cdc/redo/writer/file/file_test.go +++ b/cdc/redo/writer/file/file_test.go @@ -275,8 +275,7 @@ func TestNewFileWriter(t *testing.T) { func TestRotateFileWithFileAllocator(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() _, err := NewFileWriter(ctx, nil) require.NotNil(t, err) @@ -341,8 +340,7 @@ func TestRotateFileWithFileAllocator(t *testing.T) { func TestRotateFileWithoutFileAllocator(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() _, err := NewFileWriter(ctx, nil) require.NotNil(t, err) diff --git a/cdc/redo/writer/memory/encoding_worker.go b/cdc/redo/writer/memory/encoding_worker.go index f62f236f88..7f8fa9ffa4 100644 --- a/cdc/redo/writer/memory/encoding_worker.go +++ b/cdc/redo/writer/memory/encoding_worker.go @@ -32,12 +32,12 @@ import ( var ( eventPool = sync.Pool{ - New: func() interface{} { + New: func() any { return &polymorphicRedoEvent{} }, } dataPool = sync.Pool{ - New: func() interface{} { + New: func() any { return new(bytes.Buffer) }, } diff --git a/cdc/redo/writer/memory/file_worker.go b/cdc/redo/writer/memory/file_worker.go index f8087554db..21a48fbb54 100644 --- a/cdc/redo/writer/memory/file_worker.go +++ b/cdc/redo/writer/memory/file_worker.go @@ -135,7 +135,7 @@ func newFileWorkerGroup( extStorage: extStorage, uuidGenerator: uuid.NewGenerator(), pool: sync.Pool{ - New: func() interface{} { + New: func() any { // Use pointer here to prevent static checkers from reporting errors. // Ref: https://github.com/dominikh/go-tools/issues/1336. buf := make([]byte, 0, cfg.MaxLogSizeInBytes) diff --git a/cdc/scheduler/internal/scheduler.go b/cdc/scheduler/internal/scheduler.go index 28e241b9dd..f965619edc 100644 --- a/cdc/scheduler/internal/scheduler.go +++ b/cdc/scheduler/internal/scheduler.go @@ -72,5 +72,5 @@ type Scheduler interface { type Query struct { CaptureID model.CaptureID - Resp interface{} + Resp any } diff --git a/cdc/scheduler/internal/v3/agent/agent_test.go b/cdc/scheduler/internal/v3/agent/agent_test.go index 1b9617b3d4..0025358eb6 100644 --- a/cdc/scheduler/internal/v3/agent/agent_test.go +++ b/cdc/scheduler/internal/v3/agent/agent_test.go @@ -312,7 +312,7 @@ func TestAgentHandleMessageHeartbeat(t *testing.T) { mockTableExecutor := newMockTableExecutor() a.tableM = newTableSpanManager(model.ChangeFeedID{}, mockTableExecutor) - for i := 0; i < 5; i++ { + for i := range 5 { a.tableM.addTableSpan(spanz.TableIDToComparableSpan(int64(i))) } diff --git a/cdc/scheduler/internal/v3/coordinator_bench_test.go b/cdc/scheduler/internal/v3/coordinator_bench_test.go index 75094ba1d9..644462d374 100644 --- a/cdc/scheduler/internal/v3/coordinator_bench_test.go +++ b/cdc/scheduler/internal/v3/coordinator_bench_test.go @@ -63,11 +63,11 @@ func BenchmarkCoordinatorInit(b *testing.B) { ) { const captureCount = 8 captures = map[model.CaptureID]*model.CaptureInfo{} - for i := 0; i < captureCount; i++ { + for i := range captureCount { captures[fmt.Sprint(i)] = &model.CaptureInfo{} } currentTables = make([]model.TableID, 0, total) - for i := 0; i < total; i++ { + for i := range total { currentTables = append(currentTables, int64(10000+i)) } // Disable heartbeat. @@ -99,14 +99,14 @@ func BenchmarkCoordinatorHeartbeat(b *testing.B) { captureM := member.NewCaptureManager( "", model.ChangeFeedID{}, schedulepb.OwnerRevision{}, cfg) captureM.SetInitializedForTests(true) - for i := 0; i < captureCount; i++ { + for i := range captureCount { captures[fmt.Sprint(i)] = &model.CaptureInfo{} captureM.Captures[fmt.Sprint(i)] = &member.CaptureStatus{ State: member.CaptureStateInitialized, } } currentTables = make([]model.TableID, 0, total) - for i := 0; i < total; i++ { + for i := range total { currentTables = append(currentTables, int64(10000+i)) } coord = &coordinator{ @@ -134,7 +134,7 @@ func BenchmarkCoordinatorHeartbeatResponse(b *testing.B) { captureM := member.NewCaptureManager( "", model.ChangeFeedID{}, schedulepb.OwnerRevision{}, cfg) captureM.SetInitializedForTests(true) - for i := 0; i < captureCount; i++ { + for i := range captureCount { captures[fmt.Sprint(i)] = &model.CaptureInfo{} captureM.Captures[fmt.Sprint(i)] = &member.CaptureStatus{ State: member.CaptureStateInitialized, @@ -143,7 +143,7 @@ func BenchmarkCoordinatorHeartbeatResponse(b *testing.B) { replicationM := replication.NewReplicationManager(10, model.ChangeFeedID{}) currentTables = make([]model.TableID, 0, total) heartbeatResp := make(map[model.CaptureID]*schedulepb.Message) - for i := 0; i < total; i++ { + for i := range total { tableID := int64(10000 + i) currentTables = append(currentTables, tableID) captureID := fmt.Sprint(i % captureCount) diff --git a/cdc/scheduler/internal/v3/keyspan/reconciler.go b/cdc/scheduler/internal/v3/keyspan/reconciler.go index 021cc28aa6..6172d744b8 100644 --- a/cdc/scheduler/internal/v3/keyspan/reconciler.go +++ b/cdc/scheduler/internal/v3/keyspan/reconciler.go @@ -217,17 +217,11 @@ func (m *Reconciler) Reconcile( const maxSpanNumber = 100 func getSpansNumber(regionNum, captureNum int) int { - coefficient := captureNum - 1 - if baseSpanNumberCoefficient > coefficient { - coefficient = baseSpanNumberCoefficient - } + coefficient := max(baseSpanNumberCoefficient, captureNum-1) spanNum := 1 if regionNum > 1 { // spanNumber = max(captureNum * coefficient, totalRegions / spanRegionLimit) - spanNum = captureNum * coefficient - if regionNum/spanRegionLimit > spanNum { - spanNum = regionNum / spanRegionLimit - } + spanNum = max(regionNum/spanRegionLimit, captureNum*coefficient) } if spanNum > maxSpanNumber { spanNum = maxSpanNumber diff --git a/cdc/scheduler/internal/v3/keyspan/splitter_region_count.go b/cdc/scheduler/internal/v3/keyspan/splitter_region_count.go index 49205f928d..445deecbde 100644 --- a/cdc/scheduler/internal/v3/keyspan/splitter_region_count.go +++ b/cdc/scheduler/internal/v3/keyspan/splitter_region_count.go @@ -99,11 +99,7 @@ func (m *regionCountSplitter) split( } start = end step := stepper.Step() - if end+step < len(regions) { - end = end + step - } else { - end = len(regions) - } + end = min(end+step, len(regions)) } // Make sure spans does not exceed [startKey, endKey). spans[0].StartKey = span.StartKey diff --git a/cdc/scheduler/internal/v3/keyspan/splitter_region_count_test.go b/cdc/scheduler/internal/v3/keyspan/splitter_region_count_test.go index a42041dec5..9999066a74 100644 --- a/cdc/scheduler/internal/v3/keyspan/splitter_region_count_test.go +++ b/cdc/scheduler/internal/v3/keyspan/splitter_region_count_test.go @@ -133,10 +133,10 @@ func TestRegionCountEvenlySplitSpan(t *testing.T) { cache := NewMockRegionCache() totalRegion := 1000 - for i := 0; i < totalRegion; i++ { + for i := range totalRegion { cache.regions.ReplaceOrInsert(tablepb.Span{ - StartKey: []byte(fmt.Sprintf("t1_%09d", i)), - EndKey: []byte(fmt.Sprintf("t1_%09d", i+1)), + StartKey: fmt.Appendf(nil, "t1_%09d", i), + EndKey: fmt.Appendf(nil, "t1_%09d", i+1), }, uint64(i+1)) } diff --git a/cdc/scheduler/internal/v3/keyspan/splitter_write.go b/cdc/scheduler/internal/v3/keyspan/splitter_write.go index 653328ba61..974f71e995 100644 --- a/cdc/scheduler/internal/v3/keyspan/splitter_write.go +++ b/cdc/scheduler/internal/v3/keyspan/splitter_write.go @@ -166,7 +166,7 @@ func (m *writeSplitter) splitRegionsByWrittenKeysV1( // 3. Split the table into spans, each span has approximately // `writeWeightPerSpan` weight or `spanRegionLimit` regions. - for i := 0; i < len(regions); i++ { + for i := range regions { restRegions := len(regions) - i regionCount++ spanWriteWeight += regions[i].WrittenKeys diff --git a/cdc/scheduler/internal/v3/keyspan/splitter_write_test.go b/cdc/scheduler/internal/v3/keyspan/splitter_write_test.go index 681d1d5a52..1f8acc4979 100644 --- a/cdc/scheduler/internal/v3/keyspan/splitter_write_test.go +++ b/cdc/scheduler/internal/v3/keyspan/splitter_write_test.go @@ -215,7 +215,7 @@ func TestSplitRegionEven(t *testing.T) { tblID := model.TableID(1) regionCount := 4653 + 1051 + 745 + 9530 + 1 regions := make([]pdutil.RegionInfo, regionCount) - for i := 0; i < regionCount; i++ { + for i := range regionCount { regions[i] = pdutil.RegionInfo{ ID: uint64(i), StartKey: "" + strconv.Itoa(i), @@ -243,7 +243,7 @@ func TestSplitLargeRegion(t *testing.T) { tblID := model.TableID(1) regionCount := spanRegionLimit*5 + 1000 regions := make([]pdutil.RegionInfo, regionCount) - for i := 0; i < regionCount; i++ { + for i := range regionCount { regions[i] = pdutil.RegionInfo{ ID: uint64(i), StartKey: "" + strconv.Itoa(i), @@ -271,7 +271,7 @@ func TestSpanRegionLimitBase(t *testing.T) { splitter := newWriteSplitter(model.GenerateChangeFeedID("test", "test"), nil, 0) var regions []pdutil.RegionInfo // test spanRegionLimit works - for i := 0; i < spanRegionLimit*6; i++ { + for i := range spanRegionLimit * 6 { regions = append(regions, pdutil.NewTestRegionInfo(uint64(i+9), []byte("f"), []byte("f"), 100)) } captureNum := 2 @@ -321,17 +321,17 @@ func TestSpanRegionLimit(t *testing.T) { // random generate writtenKeys for each region var writtenKeys []int - for i := 0; i < countOver20000; i++ { + for range countOver20000 { number := rand.Intn(80000) + 20001 writtenKeys = append(writtenKeys, number) } - for i := 0; i < countBetween5000And10000; i++ { + for range countBetween5000And10000 { number := rand.Intn(5001) + 5000 writtenKeys = append(writtenKeys, number) } - for i := 0; i < countBelow1000; i++ { + for range countBelow1000 { number := rand.Intn(1000) writtenKeys = append(writtenKeys, number) } diff --git a/cdc/scheduler/internal/v3/replication/replication_manager.go b/cdc/scheduler/internal/v3/replication/replication_manager.go index 8f200f2d35..f05a2fc426 100644 --- a/cdc/scheduler/internal/v3/replication/replication_manager.go +++ b/cdc/scheduler/internal/v3/replication/replication_manager.go @@ -758,7 +758,7 @@ func (r *Manager) logSlowTableInfo(currentPDTime time.Time) { }) num := r.slowTableHeap.Len() - for i := 0; i < num; i++ { + for range num { table := heap.Pop(&r.slowTableHeap).(*ReplicationSet) log.Info("schedulerv3: slow table", zap.String("namespace", r.changefeedID.Namespace), diff --git a/cdc/scheduler/internal/v3/replication/replication_set.go b/cdc/scheduler/internal/v3/replication/replication_set.go index f3662cf419..cefaf81bf3 100644 --- a/cdc/scheduler/internal/v3/replication/replication_set.go +++ b/cdc/scheduler/internal/v3/replication/replication_set.go @@ -1090,12 +1090,12 @@ func (h SetHeap) Less(i, j int) bool { func (h SetHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } // Push pushes an element to the heap. -func (h *SetHeap) Push(x interface{}) { +func (h *SetHeap) Push(x any) { *h = append(*h, x.(*ReplicationSet)) } // Pop pops an element from the heap. -func (h *SetHeap) Pop() interface{} { +func (h *SetHeap) Pop() any { old := *h n := len(old) x := old[n-1] diff --git a/cdc/scheduler/internal/v3/replication/replication_set_test.go b/cdc/scheduler/internal/v3/replication/replication_set_test.go index d7ab23f739..dfc0f40d77 100644 --- a/cdc/scheduler/internal/v3/replication/replication_set_test.go +++ b/cdc/scheduler/internal/v3/replication/replication_set_test.go @@ -16,6 +16,7 @@ package replication import ( "container/heap" "encoding/json" + "maps" "math/rand" "testing" "time" @@ -784,9 +785,7 @@ func TestReplicationSetRemoveTable(t *testing.T) { func clone(r *ReplicationSet) *ReplicationSet { rClone := *r rClone.Captures = make(map[string]Role) - for captureID, role := range r.Captures { - rClone.Captures[captureID] = role - } + maps.Copy(rClone.Captures, r.Captures) return &rClone } @@ -1679,7 +1678,7 @@ func TestReplicationSetHeap_MinK(t *testing.T) { tables := make([]model.TableID, 0) tableCounts := h.Len() - for i := 0; i < tableCounts; i++ { + for range tableCounts { element := heap.Pop(&h).(*ReplicationSet) t.Log(element.Span) tables = append(tables, element.Span.TableID) diff --git a/cdc/scheduler/internal/v3/scheduler/scheduler_balance.go b/cdc/scheduler/internal/v3/scheduler/scheduler_balance.go index a87f4d7f8f..5192dc6b22 100644 --- a/cdc/scheduler/internal/v3/scheduler/scheduler_balance.go +++ b/cdc/scheduler/internal/v3/scheduler/scheduler_balance.go @@ -98,7 +98,7 @@ func buildBalanceMoveTables( moves := newBalanceMoveTables( random, captures, replications, maxTaskConcurrency, changeFeedID) tasks := make([]*replication.ScheduleTask, 0, len(moves)) - for i := 0; i < len(moves); i++ { + for i := range moves { // No need for accept callback here. tasks = append(tasks, &replication.ScheduleTask{MoveTable: &moves[i]}) } diff --git a/cdc/scheduler/internal/v3/scheduler/scheduler_basic_test.go b/cdc/scheduler/internal/v3/scheduler/scheduler_basic_test.go index 83d00ed36b..c821425508 100644 --- a/cdc/scheduler/internal/v3/scheduler/scheduler_basic_test.go +++ b/cdc/scheduler/internal/v3/scheduler/scheduler_basic_test.go @@ -215,11 +215,11 @@ func BenchmarkSchedulerBasicAddTables(b *testing.B) { ) { const captureCount = 8 captures = map[model.CaptureID]*member.CaptureStatus{} - for i := 0; i < captureCount; i++ { + for i := range captureCount { captures[fmt.Sprint(i)] = &member.CaptureStatus{} } currentTables = make([]tablepb.Span, 0, total) - for i := 0; i < total; i++ { + for i := range total { currentTables = append(currentTables, tablepb.Span{TableID: int64(10000 + i)}) } replications = mapToSpanMap(map[model.TableID]*replication.ReplicationSet{}) @@ -239,12 +239,12 @@ func BenchmarkSchedulerBasicRemoveTables(b *testing.B) { ) { const captureCount = 8 captures = map[model.CaptureID]*member.CaptureStatus{} - for i := 0; i < captureCount; i++ { + for i := range captureCount { captures[fmt.Sprint(i)] = &member.CaptureStatus{} } currentTables = make([]tablepb.Span, 0, total) replications = mapToSpanMap(map[model.TableID]*replication.ReplicationSet{}) - for i := 0; i < total; i++ { + for i := range total { replications.ReplaceOrInsert(tablepb.Span{TableID: int64(10000 + i)}, &replication.ReplicationSet{ Primary: fmt.Sprint(i % captureCount), @@ -266,7 +266,7 @@ func BenchmarkSchedulerBasicAddRemoveTables(b *testing.B) { ) { const captureCount = 8 captures = map[model.CaptureID]*member.CaptureStatus{} - for i := 0; i < captureCount; i++ { + for i := range captureCount { captures[fmt.Sprint(i)] = &member.CaptureStatus{} } currentTables = make([]tablepb.Span, 0, total) diff --git a/cdc/scheduler/internal/v3/transport/transport.go b/cdc/scheduler/internal/v3/transport/transport.go index 8fb2d86754..b6b0d5f327 100644 --- a/cdc/scheduler/internal/v3/transport/transport.go +++ b/cdc/scheduler/internal/v3/transport/transport.go @@ -100,7 +100,7 @@ func NewTransport( ctx, trans.selfTopic, &schedulepb.Message{}, - func(sender string, messageI interface{}) error { + func(sender string, messageI any) error { message := messageI.(*schedulepb.Message) trans.mu.Lock() trans.mu.msgBuf = append(trans.mu.msgBuf, message) diff --git a/cdc/scheduler/internal/v3/transport/transport_test.go b/cdc/scheduler/internal/v3/transport/transport_test.go index 5e5d251326..e429f81a86 100644 --- a/cdc/scheduler/internal/v3/transport/transport_test.go +++ b/cdc/scheduler/internal/v3/transport/transport_test.go @@ -14,7 +14,6 @@ package transport import ( - "context" "testing" "time" @@ -30,8 +29,7 @@ func TestTransSendRecv(t *testing.T) { cluster := p2p.NewMockCluster(t, 3) defer cluster.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeedID := model.ChangeFeedID{Namespace: "test", ID: "test"} var err error @@ -93,8 +91,7 @@ func TestTransUnknownAddr(t *testing.T) { cluster := p2p.NewMockCluster(t, 3) defer cluster.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeedID := model.ChangeFeedID{Namespace: "test", ID: "test"} var err error @@ -118,8 +115,7 @@ func TestTransEmptyRecv(t *testing.T) { cluster := p2p.NewMockCluster(t, 3) defer cluster.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeedID := model.ChangeFeedID{Namespace: "test", ID: "test"} var err error @@ -143,8 +139,7 @@ func TestTransTwoRolesInOneNode(t *testing.T) { cluster := p2p.NewMockCluster(t, 1) defer cluster.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeedID := model.ChangeFeedID{Namespace: "test", ID: "test"} for _, node := range cluster.Nodes { diff --git a/cdc/server/server_test.go b/cdc/server/server_test.go index 6301752d64..58fc77d3eb 100644 --- a/cdc/server/server_test.go +++ b/cdc/server/server_test.go @@ -202,12 +202,10 @@ func TestServerTLSWithoutCommonName(t *testing.T) { defer cancel() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.tcpServer.Run(ctx) require.ErrorContains(t, err, "ErrTCPServerClosed") - }() + }) // test cli sends request without a cert will success err = retry.Do(ctx, func() error { @@ -289,12 +287,10 @@ func TestServerTLSWithCommonNameAndRotate(t *testing.T) { defer cancel() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.tcpServer.Run(ctx) require.ErrorContains(t, err, "ErrTCPServerClosed") - }() + }) // test cli sends request without a cert will fail err = retry.Do(ctx, func() error { diff --git a/cdc/sink/ddlsink/cloudstorage/cloud_storage_ddl_sink_test.go b/cdc/sink/ddlsink/cloudstorage/cloud_storage_ddl_sink_test.go index e13603a988..bb2aa2bace 100644 --- a/cdc/sink/ddlsink/cloudstorage/cloud_storage_ddl_sink_test.go +++ b/cdc/sink/ddlsink/cloudstorage/cloud_storage_ddl_sink_test.go @@ -14,7 +14,6 @@ package cloudstorage import ( - "context" "fmt" "net/url" "os" @@ -34,8 +33,7 @@ import ( ) func TestWriteDDLEvent(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() parentDir := t.TempDir() uri := fmt.Sprintf("file:///%s?protocol=csv", parentDir) sinkURI, err := url.Parse(uri) @@ -101,8 +99,7 @@ func TestWriteDDLEvent(t *testing.T) { } func TestWriteCheckpointTs(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() parentDir := t.TempDir() uri := fmt.Sprintf("file:///%s?protocol=csv", parentDir) sinkURI, err := url.Parse(uri) @@ -146,8 +143,7 @@ func TestWriteCheckpointTs(t *testing.T) { func TestCleanupExpiredFiles(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() parentDir := t.TempDir() uri := fmt.Sprintf("file:///%s?protocol=csv", parentDir) sinkURI, err := url.Parse(uri) diff --git a/cdc/sink/ddlsink/mq/ddlproducer/kafka_ddl_producer_test.go b/cdc/sink/ddlsink/mq/ddlproducer/kafka_ddl_producer_test.go index 047ed7de21..83386c064a 100644 --- a/cdc/sink/ddlsink/mq/ddlproducer/kafka_ddl_producer_test.go +++ b/cdc/sink/ddlsink/mq/ddlproducer/kafka_ddl_producer_test.go @@ -52,7 +52,7 @@ func TestSyncBroadcastMessage(t *testing.T) { p := NewKafkaDDLProducer(ctx, changefeed, syncProducer) - for i := 0; i < kafka.DefaultMockPartitionNum; i++ { + for range kafka.DefaultMockPartitionNum { syncProducer.(*kafka.MockSaramaSyncProducer).Producer.ExpectSendMessageAndSucceed() } err = p.SyncBroadcastMessage(ctx, kafka.DefaultMockTopicName, @@ -116,8 +116,7 @@ func TestProducerSendMsgFailed(t *testing.T) { } func TestProducerDoubleClose(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() options := getOptions() ctx = context.WithValue(ctx, "testing.T", t) diff --git a/cdc/sink/ddlsink/mq/ddlproducer/pulsar_ddl_producer.go b/cdc/sink/ddlsink/mq/ddlproducer/pulsar_ddl_producer.go index ec91dd2c5a..586c594134 100644 --- a/cdc/sink/ddlsink/mq/ddlproducer/pulsar_ddl_producer.go +++ b/cdc/sink/ddlsink/mq/ddlproducer/pulsar_ddl_producer.go @@ -118,7 +118,7 @@ func NewPulsarProducer( producerCacheSize = int(*sinkConfig.PulsarConfig.PulsarProducerCacheSize) } - producers, err := lru.NewWithEvict(producerCacheSize, func(key interface{}, value interface{}) { + producers, err := lru.NewWithEvict(producerCacheSize, func(key any, value any) { // remove producer pulsarProducer, ok := value.(pulsar.Producer) if ok && pulsarProducer != nil { diff --git a/cdc/sink/ddlsink/mq/mq_ddl_sink_test.go b/cdc/sink/ddlsink/mq/mq_ddl_sink_test.go index c3dfc873c1..61881fd34d 100644 --- a/cdc/sink/ddlsink/mq/mq_ddl_sink_test.go +++ b/cdc/sink/ddlsink/mq/mq_ddl_sink_test.go @@ -31,8 +31,7 @@ func TestNewKafkaDDLSinkFailed(t *testing.T) { t.Parallel() changefeedID := model.DefaultChangeFeedID("test") - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + "&max-message-bytes=1048576&partition-num=1" + @@ -56,8 +55,7 @@ func TestWriteDDLEventToAllPartitions(t *testing.T) { t.Parallel() changefeedID := model.DefaultChangeFeedID("test") - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // partition-number is 2, so only send DDL events to 2 partitions. uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + @@ -98,8 +96,7 @@ func TestWriteDDLEventToAllPartitions(t *testing.T) { func TestWriteDDLEventToZeroPartition(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + "&max-message-bytes=1048576&partition-num=1" + @@ -141,8 +138,7 @@ func TestWriteDDLEventToZeroPartition(t *testing.T) { func TestWriteCheckpointTsToDefaultTopic(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // partition-num is set to 2, so send checkpoint to 2 partitions. uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + @@ -178,8 +174,7 @@ func TestWriteCheckpointTsToDefaultTopic(t *testing.T) { func TestWriteCheckpointTsToTableTopics(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Notice: auto create topic is true. Auto created topic will have 1 partition. uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + @@ -243,8 +238,7 @@ func TestWriteCheckpointTsToTableTopics(t *testing.T) { func TestWriteCheckpointTsWhenCanalJsonTiDBExtensionIsDisable(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Notice: tidb extension is disabled. uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + diff --git a/cdc/sink/ddlsink/mq/pulsar_ddl_sink_test.go b/cdc/sink/ddlsink/mq/pulsar_ddl_sink_test.go index d06086f768..1a5e8fed3f 100644 --- a/cdc/sink/ddlsink/mq/pulsar_ddl_sink_test.go +++ b/cdc/sink/ddlsink/mq/pulsar_ddl_sink_test.go @@ -54,8 +54,7 @@ func newPulsarConfig(t *testing.T, schema string) (*config.PulsarConfig, *url.UR // TestNewPulsarDDLSink tests the NewPulsarDDLSink func TestNewPulsarDDLSink(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() for _, schema := range pulsarSchemaList { _, sinkURI := newPulsarConfig(t, schema) changefeedID := model.DefaultChangeFeedID("test") @@ -104,8 +103,7 @@ func TestNewPulsarDDLSink(t *testing.T) { // TestPulsarDDLSinkNewSuccess tests the NewPulsarDDLSink write a event to pulsar func TestPulsarDDLSinkNewSuccess(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() for _, schema := range pulsarSchemaList { _, sinkURI := newPulsarConfig(t, schema) @@ -125,8 +123,7 @@ func TestPulsarDDLSinkNewSuccess(t *testing.T) { func TestPulsarWriteDDLEventToZeroPartition(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() for _, schema := range pulsarSchemaList { _, sinkURI := newPulsarConfig(t, schema) diff --git a/cdc/sink/ddlsink/mysql/async_ddl_test.go b/cdc/sink/ddlsink/mysql/async_ddl_test.go index 4ebdd051ad..9fd92c1552 100644 --- a/cdc/sink/ddlsink/mysql/async_ddl_test.go +++ b/cdc/sink/ddlsink/mysql/async_ddl_test.go @@ -69,8 +69,7 @@ func TestWaitAsynExecDone(t *testing.T) { }) GetDBConnImpl = dbConnFactory - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() sinkURI, err := url.Parse("mysql://root:@127.0.0.1:4000") require.NoError(t, err) replicateCfg := config.GetDefaultReplicaConfig() diff --git a/cdc/sink/ddlsink/mysql/mysql_ddl_sink_test.go b/cdc/sink/ddlsink/mysql/mysql_ddl_sink_test.go index 5a1771b458..8b0676fc63 100644 --- a/cdc/sink/ddlsink/mysql/mysql_ddl_sink_test.go +++ b/cdc/sink/ddlsink/mysql/mysql_ddl_sink_test.go @@ -61,8 +61,7 @@ func TestWriteDDLEvent(t *testing.T) { }) GetDBConnImpl = dbConnFactory - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse("mysql://127.0.0.1:4000") require.Nil(t, err) diff --git a/cdc/sink/dmlsink/blackhole/black_hole_dml_sink_test.go b/cdc/sink/dmlsink/blackhole/black_hole_dml_sink_test.go index d48c940047..c3a1c4b767 100644 --- a/cdc/sink/dmlsink/blackhole/black_hole_dml_sink_test.go +++ b/cdc/sink/dmlsink/blackhole/black_hole_dml_sink_test.go @@ -37,7 +37,7 @@ func TestWriteEventsCallback(t *testing.T) { count := 0 events := make([]*dmlsink.RowChangeCallbackableEvent, 0, 3000) - for i := 0; i < 3000; i++ { + for range 3000 { events = append(events, &dmlsink.RowChangeCallbackableEvent{ Event: row, Callback: func() { diff --git a/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink.go b/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink.go index 095ba7eb1b..51e2d71150 100644 --- a/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink.go +++ b/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink.go @@ -160,7 +160,7 @@ func NewDMLSink(ctx context.Context, workerChannels := make([]*chann.DrainableChann[eventFragment], cfg.WorkerCount) // create a group of encoding workers. - for i := 0; i < defaultEncodingConcurrency; i++ { + for i := range defaultEncodingConcurrency { encoder := encoderBuilder.Build() s.encodingWorkers[i] = newEncodingWorker(i, s.changefeedID, encoder, s.alive.msgCh.Out(), encodedOutCh) } @@ -179,9 +179,7 @@ func NewDMLSink(ctx context.Context, // the same dmlWorker. s.defragmenter = newDefragmenter(encodedOutCh, workerChannels) - s.wg.Add(1) - go func() { - defer s.wg.Done() + s.wg.Go(func() { err := s.run(wgCtx) s.alive.Lock() @@ -196,7 +194,7 @@ func NewDMLSink(ctx context.Context, case errCh <- err: } } - }() + }) return s, nil } @@ -205,7 +203,7 @@ func (s *DMLSink) run(ctx context.Context) error { eg, ctx := errgroup.WithContext(ctx) // run the encoding workers. - for i := 0; i < defaultEncodingConcurrency; i++ { + for i := range defaultEncodingConcurrency { encodingWorker := s.encodingWorkers[i] eg.Go(func() error { return encodingWorker.run(ctx) diff --git a/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink_test.go b/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink_test.go index 172199d402..d7c5f3c1b4 100644 --- a/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink_test.go +++ b/cdc/sink/dmlsink/cloudstorage/cloud_storage_dml_sink_test.go @@ -69,7 +69,7 @@ func generateTxnEvents( // assume we have a large transaction and it is splitted into 10 small transactions txns := make([]*dmlsink.TxnCallbackableEvent, 0, 10) - for i := 0; i < 10; i++ { + for i := range 10 { txn := &dmlsink.TxnCallbackableEvent{ Event: &model.SingleTableTxn{ CommitTs: 100, @@ -100,7 +100,7 @@ func generateTxnEvents( }, } tableInfo := model.WrapTableInfo(100, "test", 33, tidbTableInfo) - for j := 0; j < batch; j++ { + for j := range batch { row := &model.RowChangedEvent{ CommitTs: 100, TableInfo: tableInfo, diff --git a/cdc/sink/dmlsink/cloudstorage/defragmenter_test.go b/cdc/sink/dmlsink/cloudstorage/defragmenter_test.go index b20285dd95..12b961a4b3 100644 --- a/cdc/sink/dmlsink/cloudstorage/defragmenter_test.go +++ b/cdc/sink/dmlsink/cloudstorage/defragmenter_test.go @@ -61,7 +61,7 @@ func TestDeframenter(t *testing.T) { require.Nil(t, err) var seqNumbers []uint64 - for i := 0; i < txnCnt; i++ { + for i := range txnCnt { seqNumbers = append(seqNumbers, uint64(i+1)) } rand.Seed(time.Now().UnixNano()) @@ -78,7 +78,7 @@ func TestDeframenter(t *testing.T) { }, } tableInfo := model.WrapTableInfo(100, "test", 99, tidbTableInfo) - for i := 0; i < txnCnt; i++ { + for i := range txnCnt { go func(seq uint64) { encoder := encoderBuilder.Build() frag := eventFragment{ @@ -97,7 +97,7 @@ func TestDeframenter(t *testing.T) { rand.Seed(time.Now().UnixNano()) n := 1 + rand.Intn(1000) - for j := 0; j < n; j++ { + for j := range n { row := &model.RowChangedEvent{ PhysicalTableID: 100, TableInfo: tableInfo, diff --git a/cdc/sink/dmlsink/cloudstorage/dml_worker_test.go b/cdc/sink/dmlsink/cloudstorage/dml_worker_test.go index 381ced41f8..d2c13f29bb 100644 --- a/cdc/sink/dmlsink/cloudstorage/dml_worker_test.go +++ b/cdc/sink/dmlsink/cloudstorage/dml_worker_test.go @@ -82,7 +82,7 @@ func TestDMLWorkerRun(t *testing.T) { }, } tableInfo := model.WrapTableInfo(100, "test", 99, tidbTableInfo) - for i := 0; i < 5; i++ { + for i := range 5 { frag := eventFragment{ seqNumber: uint64(i), versionedTable: cloudstorage.VersionedTableName{ @@ -106,9 +106,9 @@ func TestDMLWorkerRun(t *testing.T) { }, encodedMsgs: []*common.Message{ { - Value: []byte(fmt.Sprintf(`{"id":%d,"database":"test","table":"table1","pkNames":[],"isDdl":false,`+ + Value: fmt.Appendf(nil, `{"id":%d,"database":"test","table":"table1","pkNames":[],"isDdl":false,`+ `"type":"INSERT","es":0,"ts":1663572946034,"sql":"","sqlType":{"c1":12,"c2":12},`+ - `"data":[{"c1":"100","c2":"hello world"}],"old":null}`, i)), + `"data":[{"c1":"100","c2":"hello world"}],"old":null}`, i), }, }, } @@ -116,11 +116,9 @@ func TestDMLWorkerRun(t *testing.T) { } var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = d.run(ctx) - }() + }) time.Sleep(4 * time.Second) // check whether files for table1 has been generated diff --git a/cdc/sink/dmlsink/cloudstorage/encoding_worker_test.go b/cdc/sink/dmlsink/cloudstorage/encoding_worker_test.go index eb3e696dd2..bbd6c0e54b 100644 --- a/cdc/sink/dmlsink/cloudstorage/encoding_worker_test.go +++ b/cdc/sink/dmlsink/cloudstorage/encoding_worker_test.go @@ -154,7 +154,7 @@ func TestEncodingWorkerRun(t *testing.T) { }, } - for i := 0; i < 3; i++ { + for i := range 3 { frag := eventFragment{ versionedTable: cloudstorage.VersionedTableName{ TableNameWithPhysicTableID: table, @@ -168,11 +168,9 @@ func TestEncodingWorkerRun(t *testing.T) { } var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = encodingWorker.run(ctx) - }() + }) cancel() encodingWorker.close() diff --git a/cdc/sink/dmlsink/factory/factory_test.go b/cdc/sink/dmlsink/factory/factory_test.go index 0f4a729ab2..6d1037aada 100644 --- a/cdc/sink/dmlsink/factory/factory_test.go +++ b/cdc/sink/dmlsink/factory/factory_test.go @@ -64,8 +64,7 @@ func newForTest(ctx context.Context, func TestSinkFactory(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() ctx = context.WithValue(ctx, "testing.T", t) uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + diff --git a/cdc/sink/dmlsink/mq/dispatcher/partition/index_value.go b/cdc/sink/dmlsink/mq/dispatcher/partition/index_value.go index 272d218292..41b0987331 100644 --- a/cdc/sink/dmlsink/mq/dispatcher/partition/index_value.go +++ b/cdc/sink/dmlsink/mq/dispatcher/partition/index_value.go @@ -73,7 +73,7 @@ func (r *IndexValueDispatcher) DispatchRowChangedEvent(row *model.RowChangedEven return 0, "", errors.ErrDispatcherFailed.GenWithStack( "index not found when dispatch event, table: %v, index: %s", row.TableInfo.GetTableName(), r.IndexName) } - for idx := 0; idx < len(names); idx++ { + for idx := range names { col := dispatchCols[offsets[idx]] if col == nil { continue diff --git a/cdc/sink/dmlsink/mq/dmlproducer/kafka_dml_producer_test.go b/cdc/sink/dmlsink/mq/dmlproducer/kafka_dml_producer_test.go index 9cec17e718..7a7d2149f6 100644 --- a/cdc/sink/dmlsink/mq/dmlproducer/kafka_dml_producer_test.go +++ b/cdc/sink/dmlsink/mq/dmlproducer/kafka_dml_producer_test.go @@ -69,12 +69,12 @@ func TestProducerAck(t *testing.T) { require.NotNil(t, producer) messageCount := 20 - for i := 0; i < messageCount; i++ { + for range messageCount { asyncProducer.(*kafka.MockSaramaAsyncProducer).AsyncProducer.ExpectInputAndSucceed() } count := atomic.NewInt64(0) - for i := 0; i < 10; i++ { + for range 10 { err = producer.AsyncSendMessage(ctx, kafka.DefaultMockTopicName, int32(0), &common.Message{ Key: []byte("test-key-1"), Value: []byte("test-value"), @@ -168,16 +168,14 @@ func TestProducerSendMsgFailed(t *testing.T) { } }(t) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case <-ctx.Done(): t.Errorf("TestProducerSendMessageFailed timed out") case err := <-errCh: require.ErrorIs(t, err, sarama.ErrMessageTooLarge) } - }() + }) wg.Wait() } @@ -186,8 +184,7 @@ func TestProducerDoubleClose(t *testing.T) { options := getOptions() errCh := make(chan error, 1) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() ctx = context.WithValue(ctx, "testing.T", t) changefeed := model.DefaultChangeFeedID("changefeed-test") diff --git a/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_mock_producer.go b/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_mock_producer.go index ea04aa2d50..ec88e6dfd5 100644 --- a/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_mock_producer.go +++ b/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_mock_producer.go @@ -74,7 +74,7 @@ func NewPulsarDMLProducerMock( producerCacheSize = int(*pulsarConfig.PulsarProducerCacheSize) } - producers, err := lru.NewWithEvict(producerCacheSize, func(key interface{}, value interface{}) { + producers, err := lru.NewWithEvict(producerCacheSize, func(key any, value any) { // remove producer pulsarProducer, ok := value.(pulsar.Producer) if ok && pulsarProducer != nil { diff --git a/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer.go b/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer.go index 0f2c77237c..3649ccff3e 100644 --- a/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer.go +++ b/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer.go @@ -96,7 +96,7 @@ func NewPulsarDMLProducer( producerCacheSize = int(*pulsarConfig.PulsarProducerCacheSize) } - producers, err := lru.NewWithEvict(producerCacheSize, func(key interface{}, value interface{}) { + producers, err := lru.NewWithEvict(producerCacheSize, func(key any, value any) { // this is call when lru Remove producer or auto remove producer pulsarProducer, ok := value.(pulsar.Producer) if ok && pulsarProducer != nil { diff --git a/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer_test.go b/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer_test.go index 5866de63ad..19e4513586 100644 --- a/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer_test.go +++ b/cdc/sink/dmlsink/mq/dmlproducer/pulsar_dml_producer_test.go @@ -49,8 +49,7 @@ func newPulsarConfig(t *testing.T, schema string) (sinkURI *url.URL, replicaConf func TestNewPulsarDMLProducer(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() for _, schema := range pulsarSchemaList { sinkURI, rc := newPulsarConfig(t, schema) @@ -77,8 +76,7 @@ func TestNewPulsarDMLProducer(t *testing.T) { func Test_pulsarDMLProducer_AsyncSendMessage(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() for _, schema := range pulsarSchemaList { _, rc := newPulsarConfig(t, schema) diff --git a/cdc/sink/dmlsink/mq/mq_dml_sink.go b/cdc/sink/dmlsink/mq/mq_dml_sink.go index c11ac8682b..ab1585f9a3 100644 --- a/cdc/sink/dmlsink/mq/mq_dml_sink.go +++ b/cdc/sink/dmlsink/mq/mq_dml_sink.go @@ -105,9 +105,7 @@ func newDMLSink( s.alive.worker = worker // Spawn a goroutine to send messages by the worker. - s.wg.Add(1) - go func() { - defer s.wg.Done() + s.wg.Go(func() { err := s.alive.worker.run(ctx) s.alive.Lock() @@ -133,7 +131,7 @@ func newDMLSink( zap.Error(err)) } } - }() + }) return s } diff --git a/cdc/sink/dmlsink/mq/mq_dml_sink_test.go b/cdc/sink/dmlsink/mq/mq_dml_sink_test.go index 56ed07a49d..7cd81e6afa 100644 --- a/cdc/sink/dmlsink/mq/mq_dml_sink_test.go +++ b/cdc/sink/dmlsink/mq/mq_dml_sink_test.go @@ -33,8 +33,7 @@ import ( func TestNewKafkaDMLSinkFailed(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + "&max-message-bytes=1048576&partition-num=1" + @@ -58,8 +57,7 @@ func TestNewKafkaDMLSinkFailed(t *testing.T) { } func TestWriteEvents(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() uriTemplate := "kafka://%s/%s?kafka-version=0.9.0.0&max-batch-size=1" + "&max-message-bytes=1048576&partition-num=1" + @@ -95,7 +93,7 @@ func TestWriteEvents(t *testing.T) { } events := make([]*dmlsink.CallbackableEvent[*model.SingleTableTxn], 0, 3000) - for i := 0; i < 3000; i++ { + for range 3000 { events = append(events, &dmlsink.TxnCallbackableEvent{ Event: &model.SingleTableTxn{ Rows: []*model.RowChangedEvent{row}, diff --git a/cdc/sink/dmlsink/mq/transformer/columnselector/column_selector.go b/cdc/sink/dmlsink/mq/transformer/columnselector/column_selector.go index a073a79bb4..4248bd76bd 100644 --- a/cdc/sink/dmlsink/mq/transformer/columnselector/column_selector.go +++ b/cdc/sink/dmlsink/mq/transformer/columnselector/column_selector.go @@ -14,6 +14,8 @@ package columnselector import ( + "slices" + filter "github.com/pingcap/tidb/pkg/util/table-filter" "github.com/pingcap/tiflow/cdc/model" "github.com/pingcap/tiflow/cdc/sink/dmlsink/mq/dispatcher" @@ -166,12 +168,10 @@ func (c *ColumnSelector) VerifyTables( partitionDispatcher := eventRouter.GetPartitionDispatcher(table.TableName.Schema, table.TableName.Table) switch v := partitionDispatcher.(type) { case *partition.ColumnsDispatcher: - for _, col := range v.Columns { - if col == columnInfo.Name.O { - return errors.ErrColumnSelectorFailed.GenWithStack( - "the filtered out column is used in the column dispatcher, "+ - "table: %v, column: %s", table.TableName, columnInfo.Name) - } + if slices.Contains(v.Columns, columnInfo.Name.O) { + return errors.ErrColumnSelectorFailed.GenWithStack( + "the filtered out column is used in the column dispatcher, "+ + "table: %v, column: %s", table.TableName, columnInfo.Name) } default: } diff --git a/cdc/sink/dmlsink/mq/worker_test.go b/cdc/sink/dmlsink/mq/worker_test.go index 4a7dd7a4c7..793012777b 100644 --- a/cdc/sink/dmlsink/mq/worker_test.go +++ b/cdc/sink/dmlsink/mq/worker_test.go @@ -90,7 +90,7 @@ func TestNonBatchEncode_SendMessages(t *testing.T) { count := 512 total := 0 expected := 0 - for i := 0; i < count; i++ { + for i := range count { expected += i bit := i @@ -107,11 +107,9 @@ func TestNonBatchEncode_SendMessages(t *testing.T) { } var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = worker.run(ctx) - }() + }) mp := p.(*dmlproducer.MockDMLProducer) require.Eventually(t, func() bool { @@ -129,8 +127,7 @@ func TestNonBatchEncode_SendMessages(t *testing.T) { func TestBatchEncode_Batch(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() worker, _ := newBatchEncodeWorker(t) defer worker.close() key := model.TopicPartitionKey{ @@ -146,7 +143,7 @@ func TestBatchEncode_Batch(t *testing.T) { Columns: model.Columns2ColumnDatas(cols, tableInfo), } - for i := 0; i < 512; i++ { + for range 512 { worker.msgChan.In() <- mqEvent{ key: key, rowEvent: &dmlsink.RowChangeCallbackableEvent{ @@ -437,11 +434,9 @@ func TestBatchEncode_SendMessages(t *testing.T) { } var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = worker.run(ctx) - }() + }) for _, event := range events { worker.msgChan.In() <- event @@ -473,12 +468,10 @@ func TestBatchEncodeWorker_Abort(t *testing.T) { defer worker.close() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := worker.run(ctx) require.Error(t, context.Canceled, err) - }() + }) cancel() wg.Wait() @@ -550,11 +543,9 @@ func TestNonBatchEncode_SendMessagesWhenTableStopping(t *testing.T) { } var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = worker.run(ctx) - }() + }) mp := p.(*dmlproducer.MockDMLProducer) require.Eventually(t, func() bool { return len(mp.GetAllEvents()) == 2 @@ -569,12 +560,10 @@ func TestNonBatchEncodeWorker_Abort(t *testing.T) { defer worker.close() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := worker.run(ctx) require.Error(t, context.Canceled, err) - }() + }) cancel() wg.Wait() diff --git a/cdc/sink/dmlsink/txn/event_test.go b/cdc/sink/dmlsink/txn/event_test.go index 29d27e1375..f7f61abd74 100644 --- a/cdc/sink/dmlsink/txn/event_test.go +++ b/cdc/sink/dmlsink/txn/event_test.go @@ -14,7 +14,7 @@ package txn import ( - "sort" + "slices" "testing" "github.com/pingcap/tidb/pkg/parser/mysql" @@ -195,7 +195,7 @@ func TestGenKeys(t *testing.T) { }} for _, tc := range testCases { keys := genTxnKeys(tc.txn) - sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] }) + slices.Sort(keys) require.Equal(t, tc.expected, keys) } } diff --git a/cdc/sink/dmlsink/txn/mysql/dml.go b/cdc/sink/dmlsink/txn/mysql/dml.go index 39dd639f06..1a53e1d8eb 100644 --- a/cdc/sink/dmlsink/txn/mysql/dml.go +++ b/cdc/sink/dmlsink/txn/mysql/dml.go @@ -25,12 +25,12 @@ import ( // prepareUpdate builds a parametrics UPDATE statement as following // sql: `UPDATE `test`.`t` SET {} = ?, {} = ? WHERE {} = ?, {} = {} LIMIT 1` // `WHERE` conditions come from `preCols` and SET clause targets come from `cols`. -func prepareUpdate(quoteTable string, preCols, cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bool) (string, []interface{}) { +func prepareUpdate(quoteTable string, preCols, cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bool) (string, []any) { var builder strings.Builder builder.WriteString("UPDATE " + quoteTable + " SET ") columnNames := make([]string, 0, len(cols)) - args := make([]interface{}, 0, len(cols)+len(preCols)) + args := make([]any, 0, len(cols)+len(preCols)) for _, col := range cols { colx := model.GetColumnDataX(col, tb) if colx.ColumnData == nil || colx.GetFlag().IsGeneratedColumn() { @@ -55,7 +55,7 @@ func prepareUpdate(quoteTable string, preCols, cols []*model.ColumnData, tb *mod if len(wargs) == 0 { return "", nil } - for i := 0; i < len(colNames); i++ { + for i := range colNames { if i > 0 { builder.WriteString(" AND ") } @@ -79,10 +79,10 @@ func prepareReplace( tb *model.TableInfo, appendPlaceHolder bool, translateToInsert bool, -) (string, []interface{}) { +) (string, []any) { var builder strings.Builder columnNames := make([]string, 0, len(cols)) - args := make([]interface{}, 0, len(cols)) + args := make([]any, 0, len(cols)) for _, col := range cols { colx := model.GetColumnDataX(col, tb) if colx.ColumnData == nil || colx.GetFlag().IsGeneratedColumn() { @@ -112,7 +112,7 @@ func prepareReplace( // representation. Because if we use the byte array respresentation, the go-sql-driver // will automatically set `_binary` charset for that column, which is not expected. // See https://github.com/go-sql-driver/mysql/blob/ce134bfc/connection.go#L267 -func appendQueryArgs(args []interface{}, col model.ColumnDataX) []interface{} { +func appendQueryArgs(args []any, col model.ColumnDataX) []any { switch v := col.Value.(type) { case []byte: cst := col.GetCharset() @@ -130,7 +130,7 @@ func appendQueryArgs(args []interface{}, col model.ColumnDataX) []interface{} { // prepareDelete builds a parametric DELETE statement as following // sql: `DELETE FROM `test`.`t` WHERE x = ? AND y >= ? LIMIT 1` -func prepareDelete(quoteTable string, cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bool) (string, []interface{}) { +func prepareDelete(quoteTable string, cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bool) (string, []any) { var builder strings.Builder builder.WriteString("DELETE FROM " + quoteTable + " WHERE ") @@ -138,8 +138,8 @@ func prepareDelete(quoteTable string, cols []*model.ColumnData, tb *model.TableI if len(wargs) == 0 { return "", nil } - args := make([]interface{}, 0, len(wargs)) - for i := 0; i < len(colNames); i++ { + args := make([]any, 0, len(wargs)) + for i := range colNames { if i > 0 { builder.WriteString(" AND ") } @@ -157,7 +157,7 @@ func prepareDelete(quoteTable string, cols []*model.ColumnData, tb *model.TableI // whereSlice builds a parametric WHERE clause as following // sql: `WHERE {} = ? AND {} > ?` -func whereSlice(cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bool) (colNames []string, args []interface{}) { +func whereSlice(cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bool) (colNames []string, args []any) { // Try to use unique key values when available for _, col := range cols { colx := model.GetColumnDataX(col, tb) @@ -170,7 +170,7 @@ func whereSlice(cols []*model.ColumnData, tb *model.TableInfo, forceReplicate bo // if no explicit row id but force replicate, use all key-values in where condition if len(colNames) == 0 && forceReplicate { colNames = make([]string, 0, len(cols)) - args = make([]interface{}, 0, len(cols)) + args = make([]any, 0, len(cols)) for _, col := range cols { colx := model.GetColumnDataX(col, tb) colNames = append(colNames, colx.GetName()) @@ -198,7 +198,7 @@ func buildColumnList(names []string) string { func placeHolder(n int) string { var builder strings.Builder builder.Grow((n-1)*2 + 1) - for i := 0; i < n; i++ { + for i := range n { if i > 0 { builder.WriteString(",") } diff --git a/cdc/sink/dmlsink/txn/mysql/dml_test.go b/cdc/sink/dmlsink/txn/mysql/dml_test.go index a3589daa8c..59e70d10fc 100644 --- a/cdc/sink/dmlsink/txn/mysql/dml_test.go +++ b/cdc/sink/dmlsink/txn/mysql/dml_test.go @@ -31,7 +31,7 @@ func TestPrepareUpdate(t *testing.T) { preCols []*model.Column cols []*model.Column expectedSQL string - expectedArgs []interface{} + expectedArgs []any }{ { quoteTable: "`test`.`t1`", @@ -66,7 +66,7 @@ func TestPrepareUpdate(t *testing.T) { {Name: "b", Type: mysql.TypeVarchar, Flag: 0, Value: "test2"}, }, expectedSQL: "UPDATE `test`.`t1` SET `a` = ?, `b` = ? WHERE `a` = ? LIMIT 1", - expectedArgs: []interface{}{1, "test2", 1}, + expectedArgs: []any{1, "test2", 1}, }, { quoteTable: "`test`.`t1`", @@ -110,7 +110,7 @@ func TestPrepareUpdate(t *testing.T) { }, }, expectedSQL: "UPDATE `test`.`t1` SET `a` = ?, `b` = ? WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{2, "test2", 1, "test"}, + expectedArgs: []any{2, "test2", 1, "test"}, }, { quoteTable: "`test`.`t1`", @@ -154,7 +154,7 @@ func TestPrepareUpdate(t *testing.T) { }, }, expectedSQL: "UPDATE `test`.`t1` SET `a` = ?, `b` = ? WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{2, []byte("世界"), 1, []byte("你好")}, + expectedArgs: []any{2, []byte("世界"), 1, []byte("你好")}, }, { quoteTable: "`test`.`t1`", @@ -201,7 +201,7 @@ func TestPrepareUpdate(t *testing.T) { }, }, expectedSQL: "UPDATE `test`.`t1` SET `a` = ?, `b` = ? WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{2, []byte("世界"), 1, []byte("你好")}, + expectedArgs: []any{2, []byte("世界"), 1, []byte("你好")}, }, { quoteTable: "`test`.`t1`", @@ -248,7 +248,7 @@ func TestPrepareUpdate(t *testing.T) { }, }, expectedSQL: "UPDATE `test`.`t1` SET `a` = ?, `b` = ? WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{2, "世界", 1, "你好"}, + expectedArgs: []any{2, "世界", 1, "你好"}, }, { quoteTable: "`test`.`t1`", @@ -279,7 +279,7 @@ func TestPrepareUpdate(t *testing.T) { }, }, expectedSQL: "UPDATE `test`.`t1` SET `a` = ?, `b` = ? WHERE `a` = ? LIMIT 1", - expectedArgs: []interface{}{1, "[1,2,3,4,5]", 1}, + expectedArgs: []any{1, "[1,2,3,4,5]", 1}, }, } for _, tc := range testCases { @@ -297,7 +297,7 @@ func TestPrepareDelete(t *testing.T) { quoteTable string preCols []*model.Column expectedSQL string - expectedArgs []interface{} + expectedArgs []any }{ { quoteTable: "`test`.`t1`", @@ -322,7 +322,7 @@ func TestPrepareDelete(t *testing.T) { }, }, expectedSQL: "DELETE FROM `test`.`t1` WHERE `a` = ? LIMIT 1", - expectedArgs: []interface{}{1}, + expectedArgs: []any{1}, }, { quoteTable: "`test`.`t1`", @@ -347,7 +347,7 @@ func TestPrepareDelete(t *testing.T) { }, }, expectedSQL: "DELETE FROM `test`.`t1` WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{1, "test"}, + expectedArgs: []any{1, "test"}, }, { quoteTable: "`test`.`t1`", @@ -371,7 +371,7 @@ func TestPrepareDelete(t *testing.T) { }, }, expectedSQL: "DELETE FROM `test`.`t1` WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{1, []byte("你好")}, + expectedArgs: []any{1, []byte("你好")}, }, { quoteTable: "`test`.`t1`", @@ -397,7 +397,7 @@ func TestPrepareDelete(t *testing.T) { }, }, expectedSQL: "DELETE FROM `test`.`t1` WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{1, []byte("你好")}, + expectedArgs: []any{1, []byte("你好")}, }, { quoteTable: "`test`.`t1`", @@ -423,7 +423,7 @@ func TestPrepareDelete(t *testing.T) { }, }, expectedSQL: "DELETE FROM `test`.`t1` WHERE `a` = ? AND `b` = ? LIMIT 1", - expectedArgs: []interface{}{1, "你好"}, + expectedArgs: []any{1, "你好"}, }, } for _, tc := range testCases { @@ -440,7 +440,7 @@ func TestWhereSlice(t *testing.T) { cols []*model.Column forceReplicate bool expectedColNames []string - expectedArgs []interface{} + expectedArgs []any }{ { cols: []*model.Column{}, @@ -465,7 +465,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: false, expectedColNames: []string{"a"}, - expectedArgs: []interface{}{1}, + expectedArgs: []any{1}, }, { cols: []*model.Column{ @@ -489,13 +489,13 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: false, expectedColNames: []string{"a", "b"}, - expectedArgs: []interface{}{1, "test"}, + expectedArgs: []any{1, "test"}, }, { cols: []*model.Column{}, forceReplicate: true, expectedColNames: []string{}, - expectedArgs: []interface{}{}, + expectedArgs: []any{}, }, { cols: []*model.Column{ @@ -514,7 +514,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: true, expectedColNames: []string{"a"}, - expectedArgs: []interface{}{1}, + expectedArgs: []any{1}, }, { cols: []*model.Column{ @@ -539,7 +539,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: true, expectedColNames: []string{"a", "b"}, - expectedArgs: []interface{}{1, "test"}, + expectedArgs: []any{1, "test"}, }, { cols: []*model.Column{ @@ -558,7 +558,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: true, expectedColNames: []string{"a", "b"}, - expectedArgs: []interface{}{1, "test"}, + expectedArgs: []any{1, "test"}, }, { cols: []*model.Column{ @@ -583,7 +583,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: true, expectedColNames: []string{"a", "b", "c"}, - expectedArgs: []interface{}{1, "test", 100}, + expectedArgs: []any{1, "test", 100}, }, { cols: []*model.Column{ @@ -608,7 +608,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: false, expectedColNames: []string{"a", "b"}, - expectedArgs: []interface{}{1, []byte("你好")}, + expectedArgs: []any{1, []byte("你好")}, }, { cols: []*model.Column{ @@ -634,7 +634,7 @@ func TestWhereSlice(t *testing.T) { }, forceReplicate: true, expectedColNames: []string{"a", "b", "c"}, - expectedArgs: []interface{}{1, "你好", 100}, + expectedArgs: []any{1, "你好", 100}, }, } for i, tc := range testCases { @@ -651,7 +651,7 @@ func TestMapReplace(t *testing.T) { quoteTable string cols []*model.Column expectedQuery string - expectedArgs []interface{} + expectedArgs []any }{ { quoteTable: "`test`.`t1`", @@ -679,7 +679,7 @@ func TestMapReplace(t *testing.T) { }, }, expectedQuery: "REPLACE INTO `test`.`t1` (`a`,`b`,`d`) VALUES ", - expectedArgs: []interface{}{1, "varchar", uint8(255)}, + expectedArgs: []any{1, "varchar", uint8(255)}, }, { quoteTable: "`test`.`t1`", @@ -706,7 +706,7 @@ func TestMapReplace(t *testing.T) { }, }, expectedQuery: "REPLACE INTO `test`.`t1` (`a`,`b`,`c`,`d`) VALUES ", - expectedArgs: []interface{}{1, "varchar", 1, uint8(255)}, + expectedArgs: []any{1, "varchar", 1, uint8(255)}, }, { quoteTable: "`test`.`t1`", @@ -741,7 +741,7 @@ func TestMapReplace(t *testing.T) { }, }, expectedQuery: "REPLACE INTO `test`.`t1` (`a`,`b`,`c`,`d`,`e`) VALUES ", - expectedArgs: []interface{}{ + expectedArgs: []any{ 1, "你好", "世界", []byte("你好,世界"), []byte("你好,世界"), }, @@ -761,12 +761,12 @@ func TestMapReplace(t *testing.T) { }, }, expectedQuery: "REPLACE INTO `test`.`t1` (`a`,`b`) VALUES ", - expectedArgs: []interface{}{"[1,-2,0.3,-4.4,55]", "[1,2,3,4,5]"}, + expectedArgs: []any{"[1,-2,0.3,-4.4,55]", "[1,2,3,4,5]"}, }, } for _, tc := range testCases { // multiple times to verify the stability of column sequence in query string - for i := 0; i < 10; i++ { + for range 10 { datas, info := model.Columns2ColumnDataForTest(tc.cols) query, args := prepareReplace(tc.quoteTable, datas, info, false, false) require.Equal(t, tc.expectedQuery, query) diff --git a/cdc/sink/dmlsink/txn/mysql/mysql.go b/cdc/sink/dmlsink/txn/mysql/mysql.go index 8331bb7aea..03b9a3fe55 100644 --- a/cdc/sink/dmlsink/txn/mysql/mysql.go +++ b/cdc/sink/dmlsink/txn/mysql/mysql.go @@ -155,7 +155,7 @@ func NewMySQLBackends( var stmtCache *lru.Cache if cachePrepStmts { - stmtCache, err = lru.NewWithEvict(prepStmtCacheSize, func(key, value interface{}) { + stmtCache, err = lru.NewWithEvict(prepStmtCacheSize, func(key, value any) { stmt := value.(*sql.Stmt) stmt.Close() }) @@ -274,7 +274,7 @@ func (s *mysqlBackend) MaxFlushInterval() time.Duration { type preparedDMLs struct { startTs []model.Ts sqls []string - values [][]interface{} + values [][]any callbacks []dmlsink.CallbackFunc rowCount int approximateSize int64 @@ -294,12 +294,12 @@ func convert2RowChanges( tidbTableInfo = model.BuildTiDBTableInfoWithoutVirtualColumns(tidbTableInfo) } - preValues := make([]interface{}, 0, len(row.PreColumns)) + preValues := make([]any, 0, len(row.PreColumns)) for _, col := range row.PreColumns { preValues = append(preValues, col.Value) } - postValues := make([]interface{}, 0, len(row.Columns)) + postValues := make([]any, 0, len(row.Columns)) for _, col := range row.Columns { postValues = append(postValues, col.Value) } @@ -357,10 +357,7 @@ func (s *mysqlBackend) groupRowsByType( event *dmlsink.TxnCallbackableEvent, tableInfo *model.TableInfo, ) (insertRows, updateRows, deleteRows [][]*sqlmodel.RowChange) { - preAllocateSize := len(event.Event.Rows) - if preAllocateSize > s.cfg.MaxTxnRow { - preAllocateSize = s.cfg.MaxTxnRow - } + preAllocateSize := min(len(event.Event.Rows), s.cfg.MaxTxnRow) insertRow := make([]*sqlmodel.RowChange, 0, preAllocateSize) updateRow := make([]*sqlmodel.RowChange, 0, preAllocateSize) @@ -418,7 +415,7 @@ func (s *mysqlBackend) batchSingleTxnDmls( event *dmlsink.TxnCallbackableEvent, tableInfo *model.TableInfo, translateToInsert bool, -) (sqls []string, values [][]interface{}) { +) (sqls []string, values [][]any) { insertRows, updateRows, deleteRows := s.groupRowsByType(event, tableInfo) // handle delete @@ -470,7 +467,7 @@ func (s *mysqlBackend) batchSingleTxnDmls( return } -func (s *mysqlBackend) genUpdateSQL(rows ...*sqlmodel.RowChange) ([]string, [][]interface{}) { +func (s *mysqlBackend) genUpdateSQL(rows ...*sqlmodel.RowChange) ([]string, [][]any) { size := 0 for _, r := range rows { size += int(r.GetApproximateDataSize()) @@ -478,11 +475,11 @@ func (s *mysqlBackend) genUpdateSQL(rows ...*sqlmodel.RowChange) ([]string, [][] if size < s.cfg.MaxMultiUpdateRowSize*len(rows) { // use multi update in one SQL sql, value := sqlmodel.GenUpdateSQL(rows...) - return []string{sql}, [][]interface{}{value} + return []string{sql}, [][]any{value} } // each row has one independent update SQL. sqls := make([]string, 0, len(rows)) - values := make([][]interface{}, 0, len(rows)) + values := make([][]any, 0, len(rows)) for _, row := range rows { sql, value := row.GenSQL(sqlmodel.DMLUpdate) sqls = append(sqls, sql) @@ -508,7 +505,7 @@ func (s *mysqlBackend) prepareDMLs() *preparedDMLs { // TODO: use a sync.Pool to reduce allocations. startTs := make([]uint64, 0, s.rows) sqls := make([]string, 0, s.rows) - values := make([][]interface{}, 0, s.rows) + values := make([][]any, 0, s.rows) callbacks := make([]dmlsink.CallbackFunc, 0, len(s.events)) // translateToInsert control the update and insert behavior. @@ -569,7 +566,7 @@ func (s *mysqlBackend) prepareDMLs() *preparedDMLs { quoteTable := firstRow.TableInfo.TableName.QuoteString() for _, row := range event.Event.Rows { var query string - var args []interface{} + var args []any // Update Event if len(row.PreColumns) != 0 && len(row.Columns) != 0 { query, args = prepareUpdate( diff --git a/cdc/sink/dmlsink/txn/mysql/mysql_test.go b/cdc/sink/dmlsink/txn/mysql/mysql_test.go index 61e120ac51..08feae6636 100644 --- a/cdc/sink/dmlsink/txn/mysql/mysql_test.go +++ b/cdc/sink/dmlsink/txn/mysql/mysql_test.go @@ -135,7 +135,7 @@ func TestPrepareDML(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{}, sqls: []string{}, - values: [][]interface{}{}, + values: [][]any{}, }, }, // delete event @@ -161,7 +161,7 @@ func TestPrepareDML(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{418658114257813514}, sqls: []string{"DELETE FROM `common_1`.`uk_without_pk` WHERE `a1` = ? AND `a3` = ? LIMIT 1"}, - values: [][]interface{}{{1, 1}}, + values: [][]any{{1, 1}}, rowCount: 1, approximateSize: 74, }, @@ -190,7 +190,7 @@ func TestPrepareDML(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{418658114257813516}, sqls: []string{"INSERT INTO `common_1`.`uk_without_pk` (`a1`,`a3`) VALUES (?,?)"}, - values: [][]interface{}{{2, 2}}, + values: [][]any{{2, 2}}, rowCount: 1, approximateSize: 63, }, @@ -219,7 +219,7 @@ func TestPrepareDML(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{418658114257813518}, sqls: []string{"INSERT INTO `common_1`.`uk_without_pk` (`a1`,`a3`) VALUES (?,?)"}, - values: [][]interface{}{{1, "[1.1,-2,3.33,-4.12,-5]"}}, + values: [][]any{{1, "[1.1,-2,3.33,-4.12,-5]"}}, rowCount: 1, approximateSize: 63, }, @@ -239,8 +239,7 @@ func TestPrepareDML(t *testing.T) { } func TestAdjustSQLMode(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() dbConnFactory := pmysql.NewDBConnectionFactoryForTest() dbConnFactory.SetStandardConnectionFactory(func(ctx context.Context, dsnStr string) (*sql.DB, error) { @@ -261,13 +260,13 @@ func TestAdjustSQLMode(t *testing.T) { type mockUnavailableMySQL struct { listener net.Listener - quit chan interface{} + quit chan any wg sync.WaitGroup } func newMockUnavailableMySQL(addr string, t *testing.T) *mockUnavailableMySQL { s := &mockUnavailableMySQL{ - quit: make(chan interface{}), + quit: make(chan any), } l, err := net.Listen("tcp", addr) require.Nil(t, err) @@ -290,12 +289,10 @@ func (s *mockUnavailableMySQL) serve(t *testing.T) { require.Error(t, err) } } else { - s.wg.Add(1) - go func() { + s.wg.Go(func() { // don't read from TCP connection, to simulate database service unavailable <-s.quit - s.wg.Done() - }() + }) } } } @@ -311,8 +308,7 @@ func TestNewMySQLTimeout(t *testing.T) { mockMySQL := newMockUnavailableMySQL(addr, t) defer mockMySQL.Stop() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse(fmt.Sprintf("mysql://%s/?read-timeout=1s&timeout=1s", addr)) require.Nil(t, err) @@ -335,8 +331,7 @@ func TestNewMySQLBackendExecDML(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" // TODO: Need to test txn sink behavior when cache-prep-stmts is true // I did some attempts to write tests when cache-prep-stmts is true, but failed. @@ -462,8 +457,7 @@ func TestExecDMLRollbackErrDatabaseNotExists(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse( "mysql://127.0.0.1:4000/?time-zone=UTC&worker-count=1&cache-prep-stmts=false") @@ -529,8 +523,7 @@ func TestExecDMLRollbackErrTableNotExists(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse( "mysql://127.0.0.1:4000/?time-zone=UTC&worker-count=1&cache-prep-stmts=false") @@ -587,7 +580,7 @@ func TestExecDMLRollbackErrRetryable(t *testing.T) { dbConnFactory := pmysql.NewDBConnectionFactoryForTest() dbConnFactory.SetStandardConnectionFactory(func(ctx context.Context, dsnStr string) (*sql.DB, error) { db, mock := newTestMockDB(t) - for i := 0; i < 2; i++ { + for range 2 { mock.ExpectBegin() mock.ExpectExec("REPLACE INTO `s1`.`t1` (`a`) VALUES (?),(?)"). WithArgs(1, 2). @@ -598,8 +591,7 @@ func TestExecDMLRollbackErrRetryable(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse( "mysql://127.0.0.1:4000/?time-zone=UTC&worker-count=1&cache-prep-stmts=false") @@ -656,8 +648,7 @@ func TestMysqlSinkNotRetryErrDupEntry(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse( "mysql://127.0.0.1:4000/?time-zone=UTC&worker-count=1&safe-mode=false" + @@ -692,8 +683,7 @@ func TestNewMySQLBackend(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse("mysql://127.0.0.1:4000/?time-zone=UTC&worker-count=1" + @@ -716,8 +706,7 @@ func TestNewMySQLBackendWithIPv6Address(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" // See https://www.ietf.org/rfc/rfc2732.txt, we have to use brackets to wrap IPv6 address. sinkURI, err := url.Parse("mysql://[::1]:3306/?time-zone=UTC&worker-count=1" + @@ -790,8 +779,7 @@ func TestMySQLSinkExecDMLError(t *testing.T) { return db, nil }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() changefeed := "test-changefeed" sinkURI, err := url.Parse( "mysql://127.0.0.1:4000/?time-zone=UTC&worker-count=1&cache-prep-stmts=false") @@ -891,7 +879,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{}, sqls: []string{}, - values: [][]interface{}{}, + values: [][]any{}, }, }, { name: "insert without PK", @@ -915,7 +903,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { sqls: []string{ "INSERT INTO `common_1`.`uk_without_pk` (`a1`,`a3`) VALUES (?,?)", }, - values: [][]interface{}{{1, 1}}, + values: [][]any{{1, 1}}, rowCount: 1, approximateSize: 63, }, @@ -939,7 +927,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{418658114257813514}, sqls: []string{"INSERT INTO `common_1`.`pk` (`a1`,`a3`) VALUES (?,?)"}, - values: [][]interface{}{{1, 1}}, + values: [][]any{{1, 1}}, rowCount: 1, approximateSize: 52, }, @@ -973,7 +961,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { "UPDATE `common_1`.`uk_without_pk` SET `a1` = ?, `a3` = ? " + "WHERE `a1` = ? AND `a3` = ? LIMIT 1", }, - values: [][]interface{}{{3, 3, 2, 2}}, + values: [][]any{{3, 3, 2, 2}}, rowCount: 1, approximateSize: 92, }, @@ -1005,7 +993,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { startTs: []model.Ts{418658114257813516}, sqls: []string{"UPDATE `common_1`.`pk` SET `a1` = ?, `a3` = ? " + "WHERE `a1` = ? AND `a3` = ? LIMIT 1"}, - values: [][]interface{}{{3, 3, 2, 2}}, + values: [][]any{{3, 3, 2, 2}}, rowCount: 1, approximateSize: 81, }, @@ -1045,7 +1033,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { "INSERT INTO `common_1`.`pk` (`a1`,`a3`) VALUES (?,?)", "INSERT INTO `common_1`.`pk` (`a1`,`a3`) VALUES (?,?)", }, - values: [][]interface{}{{3, 3}, {5, 5}}, + values: [][]any{{3, 3}, {5, 5}}, rowCount: 2, approximateSize: 104, }, @@ -1071,7 +1059,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { sqls: []string{ "REPLACE INTO `common_1`.`pk` (`a1`,`a3`) VALUES (?,?)", }, - values: [][]interface{}{{3, 3}}, + values: [][]any{{3, 3}}, rowCount: 1, approximateSize: 53, }, @@ -1115,7 +1103,7 @@ func TestMysqlSinkSafeModeOff(t *testing.T) { "REPLACE INTO `common_1`.`pk` (`a1`,`a3`) VALUES (?,?)", "REPLACE INTO `common_1`.`pk` (`a1`,`a3`) VALUES (?,?)", }, - values: [][]interface{}{{3, 3}, {5, 5}}, + values: [][]any{{3, 3}, {5, 5}}, rowCount: 2, approximateSize: 106, }, @@ -1167,7 +1155,7 @@ func TestPrepareBatchDMLs(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{}, sqls: []string{}, - values: [][]interface{}{}, + values: [][]any{}, }, }, { // delete event @@ -1203,7 +1191,7 @@ func TestPrepareBatchDMLs(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{418658114257813514}, sqls: []string{"DELETE FROM `common_1`.`uk_without_pk` WHERE (`a1` = ? AND `a3` = ?) OR (`a1` = ? AND `a3` = ?)"}, - values: [][]interface{}{{1, "你好", 2, "世界"}}, + values: [][]any{{1, "你好", 2, "世界"}}, rowCount: 2, approximateSize: 115, }, @@ -1241,7 +1229,7 @@ func TestPrepareBatchDMLs(t *testing.T) { expected: &preparedDMLs{ startTs: []model.Ts{418658114257813516}, sqls: []string{"INSERT INTO `common_1`.`uk_without_pk` (`a1`,`a3`) VALUES (?,?),(?,?)"}, - values: [][]interface{}{{1, "你好", 2, "世界"}}, + values: [][]any{{1, "你好", 2, "世界"}}, rowCount: 2, approximateSize: 89, }, @@ -1297,7 +1285,7 @@ func TestPrepareBatchDMLs(t *testing.T) { "SET `a1`=CASE WHEN `a1` = ? AND `a3` = ? THEN ? WHEN `a1` = ? AND `a3` = ? THEN ? END, " + "`a3`=CASE WHEN `a1` = ? AND `a3` = ? THEN ? WHEN `a1` = ? AND `a3` = ? THEN ? END " + "WHERE (`a1` = ? AND `a3` = ?) OR (`a1` = ? AND `a3` = ?)"}, - values: [][]interface{}{{ + values: [][]any{{ 1, "开发", 2, 3, "纽约", 4, 1, "开发", "测试", 3, "纽约", "北京", 1, "开发", 3, "纽约", }}, @@ -1399,7 +1387,7 @@ func TestPrepareBatchDMLs(t *testing.T) { "WHERE (`a1` = ? AND `a3` = ?) OR (`a1` = ? AND `a3` = ?)", "INSERT INTO `common_1`.`uk_without_pk` (`a1`,`a3`) VALUES (?,?)", }, - values: [][]interface{}{ + values: [][]any{ {1, "世界", 2, "你好"}, { 1, "开发", 2, 3, "纽约", 4, 1, "开发", "测试", 3, @@ -1464,7 +1452,7 @@ func TestPrepareBatchDMLs(t *testing.T) { "UPDATE `common_1`.`uk_without_pk` SET `a1` = ?, " + "`a3` = ? WHERE `a1` = ? AND `a3` = ? LIMIT 1", }, - values: [][]interface{}{{2, "测试", 1, "开发"}, {4, "北京", 3, "纽约"}}, + values: [][]any{{2, "测试", 1, "开发"}, {4, "北京", 3, "纽约"}}, rowCount: 2, approximateSize: 204, }, @@ -1493,7 +1481,7 @@ func TestPrepareBatchDMLs(t *testing.T) { sqls: []string{ "INSERT INTO `common_1`.`uk_without_pk` (`a1`,`a3`) VALUES (?,?)", }, - values: [][]interface{}{ + values: [][]any{ {1, "[1,2,3,4,5]"}, }, rowCount: 1, @@ -1710,7 +1698,7 @@ func TestBackendGenUpdateSQL(t *testing.T) { rows []*sqlmodel.RowChange maxMultiUpdateRowSize int expectedSQLs []string - expectedValues [][]interface{} + expectedValues [][]any }{ { []*sqlmodel.RowChange{row1, row2}, @@ -1721,7 +1709,7 @@ func TestBackendGenUpdateSQL(t *testing.T) { "`name`=CASE WHEN `id` = ? THEN ? WHEN `id` = ? THEN ? END " + "WHERE (`id` = ?) OR (`id` = ?)", }, - [][]interface{}{ + [][]any{ {1, 1, 2, 2, 1, "aa", 2, "bb", 1, 2}, }, }, @@ -1732,7 +1720,7 @@ func TestBackendGenUpdateSQL(t *testing.T) { "UPDATE `db`.`tb1` SET `id` = ?, `name` = ? WHERE `id` = ? LIMIT 1", "UPDATE `db`.`tb1` SET `id` = ?, `name` = ? WHERE `id` = ? LIMIT 1", }, - [][]interface{}{ + [][]any{ {1, "aa", 1}, {2, "bb", 2}, }, diff --git a/cdc/sink/dmlsink/txn/txn_dml_sink.go b/cdc/sink/dmlsink/txn/txn_dml_sink.go index e1ee86385f..418be5467f 100644 --- a/cdc/sink/dmlsink/txn/txn_dml_sink.go +++ b/cdc/sink/dmlsink/txn/txn_dml_sink.go @@ -119,9 +119,7 @@ func newSink(ctx context.Context, sink.workers = append(sink.workers, w) } - sink.wg.Add(1) - go func() { - defer sink.wg.Done() + sink.wg.Go(func() { err := g.Wait() sink.alive.Lock() @@ -136,7 +134,7 @@ func newSink(ctx context.Context, case errCh <- err: } } - }() + }) return sink } diff --git a/cdc/sink/dmlsink/txn/txn_dml_sink_test.go b/cdc/sink/dmlsink/txn/txn_dml_sink_test.go index fd24a2557d..0d321c3f86 100644 --- a/cdc/sink/dmlsink/txn/txn_dml_sink_test.go +++ b/cdc/sink/dmlsink/txn/txn_dml_sink_test.go @@ -64,7 +64,7 @@ func TestTxnSinkNolocking(t *testing.T) { t.Parallel() bes := make([]backend, 0, 4) - for i := 0; i < 4; i++ { + for range 4 { bes = append(bes, &blackhole{blockOnEvents: 1}) } errCh := make(chan error, 1) @@ -77,7 +77,7 @@ func TestTxnSinkNolocking(t *testing.T) { {Name: "a", Type: mysql.TypeLong}, {Name: "b", Type: mysql.TypeLong}, }, nil) - for i := 0; i < 100; i++ { + for range 100 { sinkState := new(state.TableSinkState) *sinkState = state.TableSinkSinking e := &dmlsink.CallbackableEvent[*model.SingleTableTxn]{ diff --git a/cdc/sink/tablesink/progress_tracker_test.go b/cdc/sink/tablesink/progress_tracker_test.go index bf2f7f4e84..1802608e67 100644 --- a/cdc/sink/tablesink/progress_tracker_test.go +++ b/cdc/sink/tablesink/progress_tracker_test.go @@ -130,12 +130,10 @@ func TestCloseTracker(t *testing.T) { require.Equal(t, 3, tracker.trackingCount(), "event should be added") var wg sync.WaitGroup - wg.Add(1) - go func() { + wg.Go(func() { tracker.freezeProcess() tracker.waitClosed(make(chan struct{})) - wg.Done() - }() + }) cb1() cb2() @@ -165,12 +163,10 @@ func TestCloseTrackerCancellable(t *testing.T) { }() var wg sync.WaitGroup - wg.Add(1) - go func() { + wg.Go(func() { tracker.freezeProcess() tracker.waitClosed(dead) - wg.Done() - }() + }) wg.Wait() } @@ -180,7 +176,7 @@ func TestTrackerBufferBoundary(t *testing.T) { tracker := newProgressTracker(spanz.TableIDToComparableSpan(1), 8) cbs := make([]func(), 0) - for i := 0; i < 65; i++ { + for range 65 { cbs = append(cbs, tracker.addEvent()) } require.Equal(t, 2, len(tracker.pendingEvents)) diff --git a/cdc/sink/tablesink/state/state_test.go b/cdc/sink/tablesink/state/state_test.go index b767dfac4b..bdf92dee34 100644 --- a/cdc/sink/tablesink/state/state_test.go +++ b/cdc/sink/tablesink/state/state_test.go @@ -33,7 +33,6 @@ func TestStateString(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.want, func(t *testing.T) { t.Parallel() require.Equal(t, tc.want, tc.state.String()) diff --git a/cdc/sink/tablesink/table_sink_impl_test.go b/cdc/sink/tablesink/table_sink_impl_test.go index b7c55d38f5..91900c1e4b 100644 --- a/cdc/sink/tablesink/table_sink_impl_test.go +++ b/cdc/sink/tablesink/table_sink_impl_test.go @@ -310,11 +310,9 @@ func TestClose(t *testing.T) { require.Nil(t, err) require.Len(t, sink.events, 7, "all events should be flushed") var wg sync.WaitGroup - wg.Add(1) - go func() { + wg.Go(func() { tb.Close() - wg.Done() - }() + }) require.Eventually(t, func() bool { return state.TableSinkStopping == tb.state.Load() }, time.Second, time.Millisecond*10, "table should be stopping") @@ -366,11 +364,9 @@ func TestCloseCancellable(t *testing.T) { }() var wg sync.WaitGroup - wg.Add(1) - go func() { + wg.Go(func() { tb.Close() - wg.Done() - }() + }) wg.Wait() require.Eventually(t, func() bool { return state.TableSinkStopped == tb.state.Load() @@ -399,11 +395,9 @@ func TestCloseReentrant(t *testing.T) { }() var wg sync.WaitGroup - wg.Add(1) - go func() { + wg.Go(func() { tb.Close() - wg.Done() - }() + }) wg.Wait() require.Eventually(t, func() bool { return state.TableSinkStopped == tb.state.Load() diff --git a/cdc/sink/util/helper_test.go b/cdc/sink/util/helper_test.go index 27d7553b5c..f6b4c76754 100644 --- a/cdc/sink/util/helper_test.go +++ b/cdc/sink/util/helper_test.go @@ -106,7 +106,6 @@ func TestGetTopic(t *testing.T) { } for name, tc := range testCases { - tc := tc t.Run(name, func(t *testing.T) { t.Parallel() sinkURI, err := url.Parse(tc.sinkURI) diff --git a/cmd/cdc/fips.go b/cmd/cdc/fips.go index f1054ee683..d9d40238a4 100644 --- a/cmd/cdc/fips.go +++ b/cmd/cdc/fips.go @@ -12,7 +12,6 @@ // limitations under the License. //go:build boringcrypto -// +build boringcrypto package main