From fd1741605700cf0e008d5bf062ea301237c6e0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Mon, 15 Jun 2026 10:05:17 +0200 Subject: [PATCH 1/9] Run go fix with go1.26 --- cdc/api/middleware/middleware.go | 8 +- cdc/api/util.go | 2 +- cdc/api/v2/model.go | 2 +- cdc/api/v2/unsafe_test.go | 3 +- cdc/capture/capture_test.go | 12 +- cdc/entry/mounter.go | 6 +- cdc/entry/mounter_test.go | 56 ++-- cdc/entry/schema/snapshot.go | 8 +- cdc/entry/schema_storage_test.go | 2 +- cdc/entry/schema_test.go | 6 +- cdc/entry/schema_test_helper.go | 4 +- cdc/kv/matcher.go | 4 +- cdc/kv/regionlock/region_range_lock.go | 8 +- cdc/kv/shared_client_test.go | 24 +- cdc/kv/shared_region_worker_test.go | 6 +- cdc/kv/sharedconn/conn_and_client_test.go | 27 +- cdc/model/codec/codec.go | 2 +- cdc/model/codec/v1/codec.go | 4 +- cdc/model/errors.go | 2 +- cdc/model/kv.go | 2 +- cdc/model/owner.go | 10 +- cdc/model/sink.go | 12 +- cdc/model/sink_test.go | 36 +-- cdc/owner/barrier_test.go | 2 +- cdc/owner/changefeed.go | 18 +- cdc/owner/changefeed_test.go | 8 +- cdc/owner/ddl_manager_test.go | 2 +- cdc/owner/owner.go | 4 +- cdc/owner/owner_test.go | 17 +- cdc/owner/status_provider.go | 2 +- cdc/processor/manager.go | 4 +- cdc/processor/memquota/mem_quota.go | 2 +- cdc/processor/memquota/mem_quota_test.go | 42 +-- cdc/processor/processor.go | 6 +- cdc/processor/sinkmanager/manager.go | 30 +- .../sinkmanager/redo_log_advancer_test.go | 16 +- .../sinkmanager/redo_log_worker_test.go | 30 +- .../sinkmanager/table_sink_advancer_test.go | 28 +- .../sinkmanager/table_sink_worker_test.go | 60 ++-- .../sourcemanager/sorter/factory/pebble.go | 4 +- .../sourcemanager/sorter/mounted_iter_test.go | 2 +- .../sorter/pebble/event_sorter.go | 2 +- cdc/puller/ddl_puller_test.go | 15 +- cdc/puller/frontier/frontier_bench_test.go | 4 +- cdc/puller/frontier/frontier_test.go | 8 +- cdc/puller/frontier/heap_test.go | 2 +- cdc/puller/frontier/list.go | 2 +- cdc/puller/frontier/list_test.go | 4 +- cdc/puller/memorysorter/entry_sorter_test.go | 34 +-- cdc/puller/multiplexing_puller.go | 4 +- cdc/puller/multiplexing_puller_test.go | 6 +- cdc/redo/manager.go | 7 +- cdc/redo/manager_test.go | 10 +- cdc/redo/meta_manager_test.go | 7 +- cdc/redo/reader/file.go | 5 +- cdc/redo/reader/file_test.go | 3 +- cdc/redo/reader/reader.go | 6 +- cdc/redo/writer/file/file_test.go | 6 +- cdc/redo/writer/memory/encoding_worker.go | 4 +- cdc/redo/writer/memory/file_worker.go | 2 +- cdc/scheduler/internal/scheduler.go | 2 +- cdc/scheduler/internal/v3/agent/agent_test.go | 2 +- .../internal/v3/coordinator_bench_test.go | 12 +- .../internal/v3/keyspan/reconciler.go | 10 +- .../v3/keyspan/splitter_region_count.go | 6 +- .../v3/keyspan/splitter_region_count_test.go | 6 +- .../internal/v3/keyspan/splitter_write.go | 2 +- .../v3/keyspan/splitter_write_test.go | 12 +- .../v3/replication/replication_manager.go | 2 +- .../v3/replication/replication_set.go | 4 +- .../v3/replication/replication_set_test.go | 7 +- .../v3/scheduler/scheduler_balance.go | 2 +- .../v3/scheduler/scheduler_basic_test.go | 10 +- .../internal/v3/transport/transport.go | 2 +- .../internal/v3/transport/transport_test.go | 13 +- cdc/server/server_test.go | 12 +- .../cloud_storage_ddl_sink_test.go | 10 +- .../mq/ddlproducer/kafka_ddl_producer_test.go | 5 +- .../mq/ddlproducer/pulsar_ddl_producer.go | 2 +- cdc/sink/ddlsink/mq/mq_ddl_sink_test.go | 18 +- cdc/sink/ddlsink/mq/pulsar_ddl_sink_test.go | 9 +- cdc/sink/ddlsink/mysql/async_ddl_test.go | 3 +- cdc/sink/ddlsink/mysql/mysql_ddl_sink_test.go | 3 +- .../blackhole/black_hole_dml_sink_test.go | 2 +- .../cloudstorage/cloud_storage_dml_sink.go | 10 +- .../cloud_storage_dml_sink_test.go | 4 +- .../dmlsink/cloudstorage/defragmenter_test.go | 6 +- .../dmlsink/cloudstorage/dml_worker_test.go | 12 +- .../cloudstorage/encoding_worker_test.go | 8 +- cdc/sink/dmlsink/factory/factory_test.go | 3 +- .../mq/dispatcher/partition/index_value.go | 2 +- .../mq/dmlproducer/kafka_dml_producer_test.go | 13 +- .../dmlproducer/pulsar_dml_mock_producer.go | 2 +- .../mq/dmlproducer/pulsar_dml_producer.go | 2 +- .../dmlproducer/pulsar_dml_producer_test.go | 6 +- cdc/sink/dmlsink/mq/mq_dml_sink.go | 6 +- cdc/sink/dmlsink/mq/mq_dml_sink_test.go | 8 +- .../columnselector/column_selector.go | 12 +- cdc/sink/dmlsink/mq/worker_test.go | 37 +-- cdc/sink/dmlsink/txn/event_test.go | 4 +- cdc/sink/dmlsink/txn/mysql/dml.go | 24 +- cdc/sink/dmlsink/txn/mysql/dml_test.go | 58 ++-- cdc/sink/dmlsink/txn/mysql/mysql.go | 25 +- cdc/sink/dmlsink/txn/mysql/mysql_test.go | 86 +++--- cdc/sink/dmlsink/txn/txn_dml_sink.go | 6 +- cdc/sink/dmlsink/txn/txn_dml_sink_test.go | 4 +- cdc/sink/tablesink/progress_tracker_test.go | 14 +- cdc/sink/tablesink/state/state_test.go | 1 - cdc/sink/tablesink/table_sink_impl_test.go | 18 +- cdc/sink/util/helper_test.go | 1 - cmd/cdc/fips.go | 1 - cmd/dm-worker/main_test.go | 2 +- cmd/kafka-consumer/main.go | 12 +- cmd/oauth2-server/main.go | 2 +- cmd/pulsar-consumer/main.go | 14 +- cmd/storage-consumer/main.go | 5 +- dm/chaos/cases/db.go | 2 +- dm/chaos/cases/diff.go | 2 +- dm/chaos/cases/generator.go | 2 +- dm/chaos/cases/member.go | 2 +- dm/chaos/cases/task.go | 4 +- dm/checker/checker.go | 10 +- dm/config/checking_item.go | 5 +- dm/config/checking_item_test.go | 5 +- dm/config/dbconfig/config.go | 5 +- dm/config/security_test.go | 2 +- dm/config/source_config.go | 34 +-- dm/config/source_config_test.go | 2 +- dm/config/subtask_test.go | 22 +- dm/config/task.go | 8 +- dm/config/task_test.go | 15 +- dm/ctl/common/config.go | 4 +- dm/ctl/common/util.go | 14 +- dm/ctl/master/operate_task.go | 6 +- dm/dumpling/dumpling.go | 4 +- dm/loader/checkpoint.go | 4 +- dm/loader/lightning.go | 11 +- dm/master/agent_pool.go | 4 +- dm/master/agent_pool_test.go | 14 +- dm/master/bootstrap_test.go | 2 +- dm/master/etcd_test.go | 4 +- dm/master/openapi_view_test.go | 2 +- dm/master/scheduler/latch_test.go | 16 +- dm/master/scheduler/scheduler.go | 21 +- dm/master/scheduler/scheduler_test.go | 78 ++--- dm/master/server.go | 52 ++-- dm/master/server_test.go | 34 +-- dm/master/shardddl/optimist.go | 6 +- dm/master/shardddl/pessimist.go | 6 +- dm/master/shardddl/pessimist_test.go | 24 +- dm/pkg/backoff/backoff_test.go | 10 +- dm/pkg/binlog/event/common.go | 2 +- dm/pkg/binlog/event/dml.go | 2 +- dm/pkg/binlog/event/dml_test.go | 16 +- dm/pkg/binlog/event/event.go | 2 +- dm/pkg/binlog/event/event_test.go | 20 +- dm/pkg/binlog/event/generator_test.go | 24 +- dm/pkg/binlog/event/util.go | 28 +- dm/pkg/binlog/pos_finder_test.go | 6 +- dm/pkg/binlog/reader/file.go | 8 +- dm/pkg/binlog/reader/file_test.go | 6 +- dm/pkg/binlog/reader/mock.go | 2 +- dm/pkg/binlog/reader/reader.go | 2 +- dm/pkg/binlog/reader/tcp.go | 2 +- dm/pkg/checker/primary_key.go | 2 +- dm/pkg/checker/real_checker.go | 10 +- dm/pkg/checker/table_structure.go | 15 +- dm/pkg/checker/worker_pool_test.go | 8 +- dm/pkg/conn/baseconn.go | 16 +- dm/pkg/conn/baseconn_test.go | 6 +- dm/pkg/conn/basedb.go | 25 +- dm/pkg/conn/db.go | 2 +- dm/pkg/conn/mockdb.go | 2 +- dm/pkg/election/election.go | 8 +- dm/pkg/election/election_test.go | 12 +- dm/pkg/etcdutil/etcdutil.go | 8 +- dm/pkg/etcdutil/etcdutil_test.go | 4 +- dm/pkg/func-rollback/rollback_test.go | 2 +- dm/pkg/helper/value.go | 4 +- dm/pkg/log/ctx_test.go | 2 +- dm/pkg/retry/strategy.go | 10 +- dm/pkg/retry/strategy_test.go | 6 +- dm/pkg/schema/tracker.go | 4 +- dm/pkg/schema/tracker_test.go | 2 +- dm/pkg/shardddl/optimism/keeper.go | 9 +- dm/pkg/shardddl/optimism/lock.go | 13 +- dm/pkg/shardddl/optimism/lock_test.go | 2 +- dm/pkg/shardddl/pessimism/info_test.go | 6 +- dm/pkg/shardddl/pessimism/keeper.go | 5 +- dm/pkg/shardddl/pessimism/lock.go | 5 +- dm/pkg/shardddl/pessimism/operation_test.go | 2 +- dm/pkg/storage/utils_test.go | 1 - dm/pkg/terror/adapter.go | 4 +- dm/pkg/terror/terror.go | 16 +- dm/pkg/terror/terror_test.go | 8 +- dm/pkg/upgrade/upgrade_test.go | 4 +- dm/pkg/utils/common.go | 10 +- dm/pkg/utils/common_test.go | 2 +- dm/pkg/utils/string.go | 2 +- dm/pkg/utils/string_test.go | 6 +- dm/pkg/utils/util.go | 2 +- dm/pkg/utils/util_test.go | 2 +- dm/pkg/v1dbschema/schema.go | 6 +- dm/relay/binlog_writer.go | 6 +- dm/relay/file.go | 2 +- dm/relay/file_util_test.go | 4 +- dm/relay/local_reader.go | 18 +- dm/relay/local_reader_test.go | 10 +- dm/relay/meta_test.go | 2 +- dm/relay/purge_strategy.go | 20 +- dm/relay/purger.go | 6 +- dm/relay/relay.go | 8 +- dm/relay/relay_test.go | 8 +- dm/relay/relay_writer_test.go | 4 +- dm/relay/remote_retry_test.go | 4 +- dm/simulator/mcp/mcp_test.go | 18 +- dm/simulator/mcp/uk.go | 33 +-- dm/simulator/mcp/uk_test.go | 20 +- dm/simulator/sqlgen/impl.go | 4 +- dm/simulator/sqlgen/impl_test.go | 18 +- .../binlogstream/binlog_locations_test.go | 24 +- dm/syncer/binlogstream/stream_modifier.go | 6 +- .../binlogstream/streamer_controller_test.go | 2 +- dm/syncer/causality_test.go | 18 +- dm/syncer/checkpoint.go | 31 +- dm/syncer/checkpoint_flush_worker.go | 2 +- dm/syncer/checkpoint_test.go | 14 +- dm/syncer/compactor_test.go | 55 ++-- dm/syncer/data_validator.go | 10 +- dm/syncer/data_validator_test.go | 26 +- dm/syncer/dbconn/db.go | 16 +- dm/syncer/dml.go | 28 +- dm/syncer/dml_test.go | 76 ++--- dm/syncer/dml_worker.go | 8 +- dm/syncer/dml_worker_test.go | 66 ++--- dm/syncer/expr_filter_group.go | 2 +- dm/syncer/expr_filter_group_test.go | 108 +++---- dm/syncer/job_test.go | 2 +- dm/syncer/online-ddl-tools/online_ddl.go | 6 +- dm/syncer/shardddl/optimist.go | 2 +- dm/syncer/shardddl/pessimist.go | 2 +- dm/syncer/sharding-meta/shardmeta.go | 20 +- dm/syncer/sharding-meta/shardmeta_test.go | 14 +- dm/syncer/sharding_group.go | 15 +- dm/syncer/status.go | 2 +- dm/syncer/status_test.go | 8 +- dm/syncer/syncer.go | 37 +-- dm/syncer/syncer_test.go | 274 +++++++++--------- dm/syncer/validate_worker.go | 16 +- dm/syncer/validate_worker_test.go | 34 +-- dm/syncer/validator_checkpoint.go | 38 +-- dm/syncer/validator_checkpoint_test.go | 6 +- dm/syncer/validator_cond.go | 4 +- dm/syncer/validator_cond_test.go | 6 +- dm/unit/unit.go | 2 +- dm/worker/join.go | 2 +- dm/worker/relay.go | 12 +- dm/worker/relay_test.go | 4 +- dm/worker/server.go | 6 +- dm/worker/server_test.go | 14 +- dm/worker/source_worker.go | 18 +- dm/worker/source_worker_test.go | 18 +- dm/worker/status.go | 2 +- dm/worker/subtask.go | 19 +- dm/worker/subtask_holder.go | 5 +- dm/worker/subtask_test.go | 12 +- dm/worker/task_checker.go | 6 +- dm/worker/task_checker_test.go | 4 +- engine/chaos/cases/case_fake_job.go | 6 +- engine/chaos/cases/cases.go | 1 - engine/chaos/cases/dm/case.go | 8 +- engine/chaos/cases/dm/db.go | 2 +- engine/executor/cvs/cvstask.go | 2 +- engine/executor/dm/unitholder.go | 24 +- engine/executor/dm/unitholder_test.go | 4 +- engine/executor/openapi_test.go | 6 +- engine/executor/worker/task_committer.go | 6 +- engine/executor/worker/task_runner.go | 2 +- engine/executor/worker/task_runner_test.go | 22 +- engine/framework/base_jobmaster.go | 8 +- engine/framework/base_jobmaster_test.go | 2 +- engine/framework/common.go | 2 +- .../internal/eventloop/runner_test.go | 18 +- .../framework/internal/master/mock_handle.go | 2 +- .../internal/master/worker_handle.go | 4 +- .../internal/master/worker_manager.go | 7 +- .../internal/master/worker_manager_test.go | 6 +- .../internal/worker/master_client_test.go | 6 +- engine/framework/master.go | 2 +- engine/framework/master_test.go | 6 +- engine/framework/message_router_test.go | 12 +- engine/framework/mock_master_impl.go | 4 +- engine/framework/mock_worker_util.go | 2 +- engine/framework/model/master.go | 2 +- engine/framework/model/master_test.go | 1 - engine/framework/model/worker.go | 4 +- engine/framework/registry/registry.go | 6 +- engine/framework/registry/registry_test.go | 6 +- engine/framework/worker.go | 22 +- engine/framework/worker_test.go | 14 +- engine/internal/pkg/discovery/agent_test.go | 6 +- engine/jobmaster/cvsjob/cvs_job_master.go | 2 +- engine/jobmaster/dm/api.go | 18 +- engine/jobmaster/dm/ddl_coordinator.go | 5 +- engine/jobmaster/dm/ddl_coordinator_test.go | 12 +- engine/jobmaster/dm/dm_jobmaster.go | 6 +- engine/jobmaster/dm/dm_jobmaster_test.go | 12 +- engine/jobmaster/dm/metadata/state.go | 6 +- engine/jobmaster/dm/task_manager.go | 6 +- engine/jobmaster/dm/task_manager_test.go | 6 +- engine/jobmaster/dm/worker_manager.go | 14 +- engine/jobmaster/dm/worker_manager_test.go | 8 +- engine/jobmaster/example/master_impl.go | 2 +- engine/jobmaster/fakejob/job_master.go | 2 +- engine/pkg/client/executor_group_test.go | 12 +- engine/pkg/client/internal/call_test.go | 12 +- engine/pkg/client/internal/leader_resolver.go | 6 +- .../client/internal/leader_resolver_test.go | 4 +- engine/pkg/client/test_util.go | 4 +- engine/pkg/containers/slice_queue_test.go | 22 +- engine/pkg/deps/deps.go | 8 +- engine/pkg/dm/message_agent.go | 44 ++- engine/pkg/dm/message_agent_test.go | 15 +- engine/pkg/dm/mock_message_agent.go | 6 +- engine/pkg/dm/ticker/ticker_test.go | 6 +- engine/pkg/errctx/center_test.go | 16 +- .../broker/broker_integration_test.go | 4 +- .../externalresource/broker/broker_test.go | 3 +- .../integration_test/mock_cluster.go | 12 +- .../internal/bucket/file_manager.go | 2 +- .../bucket/file_manager_integration_test.go | 8 +- .../internal/bucket/file_path_util.go | 2 +- .../bucket/resource_controller_test.go | 4 +- .../internal/local/file_manager.go | 2 +- .../internal/local/file_manager_test.go | 6 +- .../manager/gc_coordinator_test.go | 6 +- .../manager/gc_runner_test.go | 10 +- .../externalresource/manager/test_utils.go | 9 +- engine/pkg/externalresource/model/model.go | 4 +- engine/pkg/meta/client_test.go | 2 +- engine/pkg/meta/internal/etcdkv/connection.go | 2 +- .../meta/internal/etcdkv/etcd_impl_test.go | 8 +- engine/pkg/meta/internal/sqlkv/connection.go | 2 +- .../pkg/meta/internal/sqlkv/sql_impl_test.go | 30 +- engine/pkg/meta/mock/clientconn_mock.go | 6 +- .../pkg/meta/mock/simple_mockclient_test.go | 8 +- engine/pkg/meta/model/common.go | 10 +- engine/pkg/meta/model/config.go | 5 +- engine/pkg/meta/model/interfaces.go | 2 +- engine/pkg/notifier/notifier.go | 6 +- engine/pkg/notifier/notifier_test.go | 18 +- engine/pkg/orm/client.go | 2 +- engine/pkg/orm/client_test.go | 140 ++++----- engine/pkg/orm/log.go | 6 +- engine/pkg/orm/mock_test.go | 92 +++--- engine/pkg/orm/model/common.go | 2 +- engine/pkg/orm/model/executor.go | 6 +- engine/pkg/orm/model/jobop.go | 4 +- engine/pkg/p2p/message_sender.go | 8 +- .../pkg/p2p/mock_message_handler_manager.go | 2 +- engine/pkg/p2p/mock_message_sender.go | 6 +- engine/pkg/p2p/mock_message_sender_test.go | 12 +- engine/pkg/p2p/server.go | 4 +- engine/pkg/p2p/server_integration_test.go | 12 +- engine/pkg/rpcutil/middleware.go | 7 +- engine/servermaster/executor_manager.go | 6 +- engine/servermaster/executor_manager_test.go | 18 +- engine/servermaster/http_test.go | 2 - engine/servermaster/jobmanager.go | 2 +- engine/servermaster/jobmanager_test.go | 57 ++-- engine/servermaster/jobop/backoff_test.go | 2 +- engine/servermaster/jobop/operator_test.go | 2 +- engine/servermaster/server_test.go | 18 +- .../serverutil/watch_executors_test.go | 12 +- engine/servermaster/service_util_test.go | 2 +- engine/test/e2e/e2e_dm_test.go | 10 +- engine/test/e2e/e2e_node_chaos_test.go | 12 +- engine/test/mock/grpc.go | 6 +- engine/test/mock/test_server.go | 6 +- pkg/api/internal/rest/request.go | 9 +- pkg/api/internal/rest/request_test.go | 3 +- pkg/applier/redo_test.go | 9 +- pkg/causality/conflict_detector.go | 6 +- pkg/causality/internal/slots.go | 2 +- pkg/causality/internal/slots_test.go | 18 +- pkg/causality/tests/driver.go | 2 +- pkg/causality/tests/worker.go | 6 +- pkg/causality/txn_cache_test.go | 4 +- pkg/chann/chann_test.go | 78 +++-- pkg/chann/drainable_chann_test.go | 2 +- pkg/chdelay/channel_delayer_test.go | 14 +- pkg/cmd/factory/factory_impl_test.go | 4 +- pkg/cmd/server/server.go | 2 +- pkg/cmd/util/helper.go | 12 +- pkg/cmd/util/helper_test.go | 2 +- pkg/column-mapping/column.go | 10 +- pkg/column-mapping/column_test.go | 26 +- pkg/compression/compress.go | 4 +- pkg/config/replica_config.go | 2 +- pkg/config/server_config.go | 8 +- pkg/container/queue/chunkqueue.go | 22 +- pkg/container/queue/chunkqueue_test.go | 30 +- pkg/container/queue/iterator_test.go | 22 +- pkg/container/sortmap/sort.go | 7 +- pkg/diff/checkpoint.go | 4 +- pkg/diff/diff.go | 4 +- pkg/diff/merge.go | 4 +- pkg/diff/merge_test.go | 2 +- pkg/diff/spliter_test.go | 32 +- pkg/diff/util.go | 8 +- pkg/election/elector_test.go | 32 +- pkg/election/storage_orm.go | 2 +- pkg/election/storage_sql_test.go | 3 +- pkg/errors/helper.go | 4 +- pkg/errors/helper_test.go | 4 +- pkg/etcd/client.go | 10 +- pkg/etcd/client_test.go | 3 +- pkg/etcd/etcd.go | 2 +- pkg/etcd/etcd_test.go | 5 +- pkg/etcd/util_test.go | 2 +- pkg/filter/expr_filter_bench_test.go | 14 +- pkg/filter/expr_filter_test.go | 120 ++++---- pkg/filter/filter.go | 9 +- pkg/filter/sql_event_filter_test.go | 1 - pkg/filter/utils.go | 8 +- pkg/fsutil/file_allocator.go | 6 +- pkg/fsutil/file_allocator_test.go | 2 +- pkg/importer/db.go | 4 +- pkg/importer/job.go | 6 +- pkg/importer/parser.go | 33 ++- pkg/label/label_test.go | 2 - pkg/label/selector_test.go | 10 +- pkg/leakutil/leak_helper_test.go | 2 +- pkg/logutil/log.go | 7 +- pkg/logutil/log_test.go | 6 +- pkg/migrate/migrate_test.go | 50 ++-- pkg/notify/notify_test.go | 22 +- pkg/orchestrator/batch.go | 6 +- pkg/orchestrator/batch_test.go | 8 +- pkg/orchestrator/etcd_worker_bank_test.go | 12 +- pkg/orchestrator/etcd_worker_test.go | 12 +- pkg/orchestrator/reactor_state.go | 17 +- pkg/p2p/client.go | 8 +- pkg/p2p/client_batch_sender.go | 5 +- pkg/p2p/client_batch_sender_test.go | 16 +- pkg/p2p/client_connector_test.go | 6 +- pkg/p2p/grpc_client.go | 11 +- pkg/p2p/grpc_client_test.go | 18 +- pkg/p2p/internal/send_chan_test.go | 58 ++-- pkg/p2p/message_router.go | 6 +- pkg/p2p/message_router_test.go | 40 +-- pkg/p2p/mock_cluster.go | 20 +- pkg/p2p/model.go | 2 +- pkg/p2p/serializer.go | 4 +- pkg/p2p/server.go | 16 +- pkg/p2p/server_ack_manager.go | 2 +- pkg/p2p/server_client_integration_test.go | 98 +++---- pkg/p2p/server_stream_handle_test.go | 12 +- pkg/p2p/server_test.go | 172 ++++------- pkg/p2p/server_wrapper_test.go | 6 +- pkg/pdutil/api_client_test.go | 13 +- pkg/pdutil/clock_test.go | 3 +- pkg/retry/retry_test.go | 2 +- pkg/security/credential.go | 2 +- pkg/security/sasl_test.go | 2 - pkg/sink/cloudstorage/path_test.go | 15 +- pkg/sink/cloudstorage/table_definition.go | 16 +- .../cloudstorage/table_definition_test.go | 2 +- pkg/sink/codec/avro/avro.go | 50 ++-- pkg/sink/codec/avro/avro_test.go | 29 +- .../avro/confluent_schema_registry_test.go | 14 +- pkg/sink/codec/avro/decoder.go | 46 +-- pkg/sink/codec/bootstraper.go | 4 +- pkg/sink/codec/bootstraper_test.go | 3 +- pkg/sink/codec/canal/canal_entry.go | 4 +- pkg/sink/codec/canal/canal_json_decoder.go | 20 +- pkg/sink/codec/canal/canal_json_message.go | 16 +- pkg/sink/codec/common/helper.go | 16 +- pkg/sink/codec/common/verify_checksum.go | 6 +- pkg/sink/codec/craft/craft_encoder_test.go | 4 +- pkg/sink/codec/craft/message_decoder.go | 18 +- pkg/sink/codec/craft/message_encoder.go | 2 +- pkg/sink/codec/csv/csv_decoder_test.go | 2 +- pkg/sink/codec/csv/csv_message_test.go | 2 +- pkg/sink/codec/debezium/codec.go | 2 +- pkg/sink/codec/debezium/debezium_test.go | 2 +- pkg/sink/codec/debezium/decoder.go | 38 +-- pkg/sink/codec/encoder.go | 2 +- pkg/sink/codec/maxwell/maxwell_message.go | 28 +- .../codec/maxwell/maxwell_message_test.go | 2 +- pkg/sink/codec/open/open_protocol_decoder.go | 14 +- .../codec/open/open_protocol_encoder_test.go | 4 +- pkg/sink/codec/simple/avro.go | 184 ++++++------ pkg/sink/codec/simple/decoder.go | 6 +- pkg/sink/codec/simple/encoder_test.go | 13 +- pkg/sink/codec/simple/marshaller.go | 2 +- pkg/sink/codec/simple/message.go | 36 +-- pkg/sink/codec/utils/test_utils.go | 2 +- pkg/sink/kafka/options_test.go | 38 +-- pkg/sink/kafka/sarama_test.go | 2 - pkg/sink/observer/observer_test.go | 8 +- pkg/sink/observer/tidb.go | 18 +- pkg/sink/pulsar/logger.go | 18 +- pkg/spanz/btree_map_test.go | 2 +- pkg/spanz/convert.go | 7 +- pkg/spanz/convert_test.go | 2 +- pkg/spanz/hash_map_test.go | 2 +- pkg/spanz/map_bench_test.go | 2 +- pkg/sqlmodel/causality.go | 16 +- pkg/sqlmodel/causality_fk_test.go | 4 +- pkg/sqlmodel/causality_test.go | 60 ++-- pkg/sqlmodel/multirow.go | 10 +- pkg/sqlmodel/multirow_bench_test.go | 12 +- pkg/sqlmodel/multirow_test.go | 54 ++-- pkg/sqlmodel/reduce.go | 16 +- pkg/sqlmodel/reduce_test.go | 76 ++--- pkg/sqlmodel/row_change.go | 28 +- pkg/sqlmodel/row_change_test.go | 112 +++---- pkg/sqlmodel/utils.go | 10 +- pkg/sqlmodel/where_handle.go | 2 +- pkg/sqlmodel/where_handle_test.go | 6 +- pkg/tcpserver/tcp_server_test.go | 84 ++---- pkg/upstream/manager.go | 6 +- pkg/upstream/upstream.go | 6 +- pkg/upstream/upstream_test.go | 7 +- pkg/util/atomic_test.go | 6 +- pkg/util/json_writer.go | 2 +- pkg/util/seahash/seahash_test.go | 2 +- pkg/util/test_helper_test.go | 2 +- pkg/uuid/uuid_test.go | 2 +- pkg/version/check_test.go | 4 +- pkg/workerpool/async_pool_test.go | 4 +- pkg/workerpool/pool.go | 6 +- pkg/workerpool/pool_impl.go | 10 +- pkg/workerpool/pool_test.go | 66 ++--- .../checkpoints/checkpoints.go | 4 +- .../checkpoints/checkpoints_test.go | 4 +- sync_diff_inspector/chunk/chunk.go | 5 +- sync_diff_inspector/diff/diff.go | 6 +- sync_diff_inspector/report/report.go | 5 +- sync_diff_inspector/report/report_test.go | 10 +- .../source/common/common_test.go | 2 +- sync_diff_inspector/source/common/rows.go | 4 +- sync_diff_inspector/source/source.go | 2 +- sync_diff_inspector/source/source_test.go | 12 +- sync_diff_inspector/source/tidb.go | 2 +- sync_diff_inspector/splitter/index_fields.go | 2 +- sync_diff_inspector/splitter/limit.go | 2 +- sync_diff_inspector/splitter/splitter_test.go | 191 ++++++------ sync_diff_inspector/utils/pd.go | 2 +- sync_diff_inspector/utils/utils.go | 20 +- sync_diff_inspector/utils/utils_test.go | 2 +- tests/integration_tests/api_v2/cases.go | 2 +- tests/integration_tests/api_v2/model.go | 2 +- tests/integration_tests/api_v2/request.go | 9 +- tests/integration_tests/bank/case.go | 12 +- tests/integration_tests/cdc/dailytest/case.go | 38 ++- tests/integration_tests/cdc/dailytest/db.go | 26 +- tests/integration_tests/cdc/dailytest/job.go | 14 +- .../integration_tests/cdc/dailytest/parser.go | 33 ++- tests/integration_tests/ddl_wait/test.go | 4 +- .../integration_tests/ddl_with_exists/test.go | 12 +- tests/integration_tests/default_value/main.go | 28 +- .../http_proxies/run-proxy.go | 2 +- tests/integration_tests/many_pk_or_uk/main.go | 4 +- tests/integration_tests/multi_source/main.go | 16 +- tests/integration_tests/resolve_lock/main.go | 8 +- tests/integration_tests/util/db.go | 4 +- tests/mq_protocol_tests/cases/case_alter.go | 6 +- .../cases/case_composite_pkey.go | 6 +- .../mq_protocol_tests/cases/case_date_time.go | 2 +- tests/mq_protocol_tests/cases/case_delete.go | 8 +- .../cases/case_handle_key.go | 6 +- .../cases/case_many_types.go | 2 +- tests/mq_protocol_tests/cases/case_simple.go | 8 +- .../mq_protocol_tests/cases/case_unsigned.go | 2 +- .../framework/avro/kafka_docker_env.go | 2 +- .../mq_protocol_tests/framework/docker_env.go | 2 +- tests/mq_protocol_tests/framework/env.go | 4 +- .../framework/sql_batch_op.go | 16 +- .../mq_protocol_tests/framework/sql_helper.go | 40 +-- 581 files changed, 3382 insertions(+), 4253 deletions(-) diff --git a/cdc/api/middleware/middleware.go b/cdc/api/middleware/middleware.go index ce3ee800af..64004948f9 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" @@ -154,11 +155,8 @@ func verify(ctx *gin.Context, up *upstream.Upstream) error { allowed := false serverCfg := config.GetGlobalServerConfig() - for _, user := range serverCfg.Security.ClientAllowedUser { - if user == username { - allowed = true - break - } + if slices.Contains(serverCfg.Security.ClientAllowedUser, username) { + allowed = true } if !allowed { errMsg := "The user is not allowed." 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..37cd58505d 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,15 @@ 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) + s.WriteString(fmt.Sprintf("%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 diff --git a/cmd/dm-worker/main_test.go b/cmd/dm-worker/main_test.go index 1e3f7dcee0..29caa27b8d 100644 --- a/cmd/dm-worker/main_test.go +++ b/cmd/dm-worker/main_test.go @@ -32,7 +32,7 @@ func TestRunMain(_ *testing.T) { var ( args []string exit = make(chan int) - waitCh = make(chan interface{}, 1) + waitCh = make(chan any, 1) ) for _, arg := range os.Args { switch { diff --git a/cmd/kafka-consumer/main.go b/cmd/kafka-consumer/main.go index 580a31fba5..f3b620e6e1 100644 --- a/cmd/kafka-consumer/main.go +++ b/cmd/kafka-consumer/main.go @@ -84,19 +84,15 @@ func main() { var wg sync.WaitGroup if consumerOption.enableProfiling { log.Info("profiling is enabled") - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if err = http.ListenAndServe(":6060", nil); err != nil { log.Panic("cannot start the pprof", zap.Error(err)) } - }() + }) } - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { consumer.Consume(ctx) - }() + }) sigterm := make(chan os.Signal, 1) signal.Notify(sigterm, syscall.SIGINT, syscall.SIGTERM) diff --git a/cmd/oauth2-server/main.go b/cmd/oauth2-server/main.go index 1385bfc4bb..f8018cf7ab 100644 --- a/cmd/oauth2-server/main.go +++ b/cmd/oauth2-server/main.go @@ -152,7 +152,7 @@ func run(_ *cobra.Command, _ []string) { } }))) http.Handle("/.well-known/openid-configuration", logMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, _ = w.Write([]byte(fmt.Sprintf(openIDConfiguration, serverConfig.port, serverConfig.port, serverConfig.port))) + _, _ = w.Write(fmt.Appendf(nil, openIDConfiguration, serverConfig.port, serverConfig.port, serverConfig.port)) w.WriteHeader(200) }))) log.Info("starting auth2 server", zap.Int("port", serverConfig.port)) diff --git a/cmd/pulsar-consumer/main.go b/cmd/pulsar-consumer/main.go index 1159b04409..ad94c87580 100644 --- a/cmd/pulsar-consumer/main.go +++ b/cmd/pulsar-consumer/main.go @@ -206,9 +206,7 @@ func run(_ *cobra.Command, _ []string) { msgChan := pulsarConsumer.Chan() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { select { case <-ctx.Done(): @@ -228,17 +226,15 @@ func run(_ *cobra.Command, _ []string) { } } } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if err = consumer.Run(ctx); err != nil { if err != context.Canceled { log.Panic("Error running consumer", zap.Error(err)) } } - }() + }) log.Info("TiCDC consumer up and running!...") sigterm := make(chan os.Signal, 1) @@ -692,7 +688,7 @@ func flushRowChangedEvents(ctx context.Context, sink *partitionSinks, resolvedTs default: } flushedResolvedTs := true - sink.tablesCommitTsMap.Range(func(key, value interface{}) bool { + sink.tablesCommitTsMap.Range(func(key, value any) bool { tableID := key.(int64) resolvedTs := model.NewResolvedTs(resolvedTs) tableSink, ok := sink.tableSinksMap.Load(tableID) diff --git a/cmd/storage-consumer/main.go b/cmd/storage-consumer/main.go index a137217724..8f3ae20bf1 100644 --- a/cmd/storage-consumer/main.go +++ b/cmd/storage-consumer/main.go @@ -18,6 +18,7 @@ import ( "encoding/json" "flag" "fmt" + "maps" "net/http" "net/url" "os" @@ -255,9 +256,7 @@ func (c *consumer) getNewFiles( opt := &storeapi.WalkOption{SubDir: ""} origDMLIdxMap := make(map[cloudstorage.DmlPathKey]uint64, len(c.tableDMLIdxMap)) - for k, v := range c.tableDMLIdxMap { - origDMLIdxMap[k] = v - } + maps.Copy(origDMLIdxMap, c.tableDMLIdxMap) err := c.externalStorage.WalkDir(ctx, opt, func(path string, size int64) error { if cloudstorage.IsSchemaFile(path) { diff --git a/dm/chaos/cases/db.go b/dm/chaos/cases/db.go index daf80cb985..6e0cc2a6e8 100644 --- a/dm/chaos/cases/db.go +++ b/dm/chaos/cases/db.go @@ -86,7 +86,7 @@ func (c *dbConn) execSQLs(ctx context.Context, queries ...string) error { } _, _, err := c.baseConn.ApplyRetryStrategy(tcontext.NewContext(ctx, log.L()), params, - func(tctx *tcontext.Context) (interface{}, error) { + func(tctx *tcontext.Context) (any, error) { ret, err2 := c.baseConn.ExecuteSQLWithIgnoreError(tctx, nil, "chaos-cases", ignoreExecSQLError, queries) return ret, err2 }) diff --git a/dm/chaos/cases/diff.go b/dm/chaos/cases/diff.go index cbf217ab4d..d98b061b71 100644 --- a/dm/chaos/cases/diff.go +++ b/dm/chaos/cases/diff.go @@ -28,7 +28,7 @@ import ( // diffDataLoop checks whether target has the same data with source via `sync-diff-inspector` multiple times. func diffDataLoop(ctx context.Context, count int, interval time.Duration, schema string, tables []string, targetDB *sql.DB, sourceDBs ...*sql.DB) (err error) { - for i := 0; i < count; i++ { + for i := range count { select { case <-ctx.Done(): return nil diff --git a/dm/chaos/cases/generator.go b/dm/chaos/cases/generator.go index 3c50a6d1e0..f5a2921dbb 100644 --- a/dm/chaos/cases/generator.go +++ b/dm/chaos/cases/generator.go @@ -222,7 +222,7 @@ func (g *CaseGenerator) genSQLs(ctx context.Context) { for _, table := range g.tables { rand.Shuffle(len(g.testCases), func(i, j int) { g.testCases[i], g.testCases[j] = g.testCases[j], g.testCases[i] }) casesNum := rand.Intn(len(g.testCases) + 1) - for i := 0; i < casesNum; i++ { + for i := range casesNum { for _, sqls := range g.testCases[i] { fullSqls := make(SQLs, len(sqls)) copy(fullSqls, sqls) diff --git a/dm/chaos/cases/member.go b/dm/chaos/cases/member.go index d7b3e9b621..91154a5b0c 100644 --- a/dm/chaos/cases/member.go +++ b/dm/chaos/cases/member.go @@ -30,7 +30,7 @@ const ( // checkMembersReadyLoop checks whether all DM-master and DM-worker members have been ready. // NOTE: in this chaos case, we ensure 3 DM-master and 3 DM-worker started. func checkMembersReadyLoop(ctx context.Context, cli pb.MasterClient, masterCount, workerCount int) (err error) { - for i := 0; i < checkMemberTimes; i++ { + for range checkMemberTimes { select { case <-ctx.Done(): return nil diff --git a/dm/chaos/cases/task.go b/dm/chaos/cases/task.go index 24cece74e3..88fa6109db 100644 --- a/dm/chaos/cases/task.go +++ b/dm/chaos/cases/task.go @@ -224,7 +224,7 @@ func (t *task) genFullData() error { ) // generate `CREATE TABLE` statements. - for i := 0; i < tableCount; i++ { + for range tableCount { query, name, err := t.ss[0].CreateTableStmt() if err != nil { return err @@ -258,7 +258,7 @@ func (t *task) genFullData() error { for _, conn := range t.sourceConns { conn2 := conn eg.Go(func() error { - for i := 0; i < fullInsertCount; i++ { + for range fullInsertCount { query, _, err2 := t.ss[0].InsertStmt(false) if err2 != nil { return err2 diff --git a/dm/checker/checker.go b/dm/checker/checker.go index 69e6eb076a..851b5ce79f 100644 --- a/dm/checker/checker.go +++ b/dm/checker/checker.go @@ -235,7 +235,7 @@ func (c *Checker) getTablePairInfo(ctx context.Context) (info *tablePairInfo, er pool := checker.NewWorkerPoolWithContext[job, int64](ctx, func(result int64) { info.totalDataSize.Add(result) }) - for i := 0; i < concurrency; i++ { + for range concurrency { pool.Go(func(ctx context.Context, job job) (int64, error) { return conn.FetchTableEstimatedBytes( ctx, @@ -644,7 +644,7 @@ func (c *Checker) Process(ctx context.Context, pr chan pb.ProcessResult) { if result.Summary.Successful != result.Summary.Total { rawResult, err = json.MarshalIndent(result, "\t", "\t") if err != nil { - rawResult = []byte(fmt.Sprintf("marshal error %v", err)) + rawResult = fmt.Appendf(nil, "marshal error %v", err) } } c.result.Lock() @@ -830,14 +830,14 @@ func (c *Checker) IsFreshTask() (bool, error) { } // Status implements Unit interface. -func (c *Checker) Status(_ *binlog.SourceStatus) interface{} { +func (c *Checker) Status(_ *binlog.SourceStatus) any { c.result.RLock() res := c.result.detail c.result.RUnlock() rawResult, err := json.Marshal(res) if err != nil { - rawResult = []byte(fmt.Sprintf("marshal %+v error %v", res, err)) + rawResult = fmt.Appendf(nil, "marshal %+v error %v", res, err) } return &pb.CheckStatus{ @@ -851,7 +851,7 @@ func (c *Checker) Status(_ *binlog.SourceStatus) interface{} { } // Error implements Unit interface. -func (c *Checker) Error() interface{} { +func (c *Checker) Error() any { return &pb.CheckError{} } diff --git a/dm/config/checking_item.go b/dm/config/checking_item.go index 777548b67c..f2821ceb16 100644 --- a/dm/config/checking_item.go +++ b/dm/config/checking_item.go @@ -16,6 +16,7 @@ package config import ( "bytes" "fmt" + "maps" "github.com/pingcap/tiflow/dm/pkg/terror" ) @@ -130,9 +131,7 @@ func SupportCheckingItems() string { // FilterCheckingItems filters ignored items from all checking items. func FilterCheckingItems(ignoredItems []string) map[string]string { checkingItems := make(map[string]string) - for item, desc := range AllCheckingItems { - checkingItems[item] = desc - } + maps.Copy(checkingItems, AllCheckingItems) delete(checkingItems, AllChecking) for _, item := range ignoredItems { diff --git a/dm/config/checking_item_test.go b/dm/config/checking_item_test.go index 1de7b91e16..2eb6dab2b8 100644 --- a/dm/config/checking_item_test.go +++ b/dm/config/checking_item_test.go @@ -14,6 +14,7 @@ package config import ( + "maps" "testing" "github.com/stretchr/testify/require" @@ -45,9 +46,7 @@ func TestCheckingItems(t *testing.T) { // ignore shard checking items checkingItems := make(map[string]string) - for item, desc := range AllCheckingItems { - checkingItems[item] = desc - } + maps.Copy(checkingItems, AllCheckingItems) delete(checkingItems, AllChecking) require.Equal(t, checkingItems, FilterCheckingItems(ignoredCheckingItems[:0])) diff --git a/dm/config/dbconfig/config.go b/dm/config/dbconfig/config.go index da57eb98b2..64c76ec420 100644 --- a/dm/config/dbconfig/config.go +++ b/dm/config/dbconfig/config.go @@ -16,6 +16,7 @@ package dbconfig import ( "bytes" "encoding/json" + "maps" "strings" "github.com/BurntSushi/toml" @@ -150,9 +151,7 @@ func (db *DBConfig) Clone() *DBConfig { if db.Session != nil { clone.Session = make(map[string]string, len(db.Session)) - for k, v := range db.Session { - clone.Session[k] = v - } + maps.Copy(clone.Session, db.Session) } clone.Security = db.Security.Clone() diff --git a/dm/config/security_test.go b/dm/config/security_test.go index ce763f9802..cb702e1842 100644 --- a/dm/config/security_test.go +++ b/dm/config/security_test.go @@ -165,7 +165,7 @@ func (c *testTLSConfig) TestClone() { } // When add new fields, also update this value // TODO: check it - c.Require().Equal(10, reflect.TypeOf(*s).NumField()) + c.Require().Equal(10, reflect.TypeFor[security.Security]().NumField()) clone := s.Clone() c.Require().Equal(s, clone) clone.CertAllowedCN[0] = "g" diff --git a/dm/config/source_config.go b/dm/config/source_config.go index 9c0ab5e7e1..96a63e6cfc 100644 --- a/dm/config/source_config.go +++ b/dm/config/source_config.go @@ -98,7 +98,7 @@ type SourceConfig struct { ServerID uint32 `yaml:"server-id" toml:"server-id" json:"server-id"` // deprecated tracer, to keep compatibility with older version - Tracer map[string]interface{} `yaml:"tracer" toml:"tracer" json:"-"` + Tracer map[string]any `yaml:"tracer" toml:"tracer" json:"-"` CaseSensitive bool `yaml:"case-sensitive" toml:"case-sensitive" json:"case-sensitive"` Filters []*bf.BinlogEventRule `yaml:"filters" toml:"filters" json:"filters"` @@ -366,7 +366,7 @@ func (c *SourceConfig) AdjustServerID(ctx context.Context, db *conn.BaseDB) erro } rand.Seed(time.Now().UnixNano()) - for i := 0; i < 5; i++ { + for range 5 { randomValue := uint32(rand.Intn(100000)) randomServerID := defaultBaseServerID + randomValue if _, ok := serverIDs[randomServerID]; ok { @@ -403,21 +403,21 @@ func (c *SourceConfig) YamlForDowngrade() (string, error) { // This config is used for downgrade(config export) from a higher dmctl version. // When we add any new config item into SourceConfig, we should update it also. type SourceConfigForDowngrade struct { - Enable bool `yaml:"enable,omitempty"` - EnableGTID bool `yaml:"enable-gtid"` - RelayDir string `yaml:"relay-dir"` - Flavor string `yaml:"flavor"` - Charset string `yaml:"charset"` - EnableRelay bool `yaml:"enable-relay"` - RelayBinLogName string `yaml:"relay-binlog-name"` - RelayBinlogGTID string `yaml:"relay-binlog-gtid"` - UUIDSuffix int `yaml:"-"` - SourceID string `yaml:"source-id"` - From dbconfig.DBConfig `yaml:"from"` - Purge PurgeConfig `yaml:"purge"` - Checker CheckerConfig `yaml:"checker"` - ServerID uint32 `yaml:"server-id"` - Tracer map[string]interface{} `yaml:"tracer"` + Enable bool `yaml:"enable,omitempty"` + EnableGTID bool `yaml:"enable-gtid"` + RelayDir string `yaml:"relay-dir"` + Flavor string `yaml:"flavor"` + Charset string `yaml:"charset"` + EnableRelay bool `yaml:"enable-relay"` + RelayBinLogName string `yaml:"relay-binlog-name"` + RelayBinlogGTID string `yaml:"relay-binlog-gtid"` + UUIDSuffix int `yaml:"-"` + SourceID string `yaml:"source-id"` + From dbconfig.DBConfig `yaml:"from"` + Purge PurgeConfig `yaml:"purge"` + Checker CheckerConfig `yaml:"checker"` + ServerID uint32 `yaml:"server-id"` + Tracer map[string]any `yaml:"tracer"` // any new config item, we mark it omitempty CaseSensitive bool `yaml:"case-sensitive,omitempty"` Filters []*bf.BinlogEventRule `yaml:"filters,omitempty"` diff --git a/dm/config/source_config_test.go b/dm/config/source_config_test.go index 27f459bcff..e454707195 100644 --- a/dm/config/source_config_test.go +++ b/dm/config/source_config_test.go @@ -71,7 +71,7 @@ func TestConfigFunctions(t *testing.T) { require.NoError(t, err) require.Equal(t, uint32(100), cfg1.ServerID) cfg.Filters = []*bf.BinlogEventRule{} - cfg.Tracer = map[string]interface{}{} + cfg.Tracer = map[string]any{} var cfg2 SourceConfig require.NoError(t, cfg2.FromToml(originCfgStr)) diff --git a/dm/config/subtask_test.go b/dm/config/subtask_test.go index d91fc2ea03..5d40d6e4e6 100644 --- a/dm/config/subtask_test.go +++ b/dm/config/subtask_test.go @@ -462,14 +462,12 @@ func TestSubTaskConfigMarshalAtomic(t *testing.T) { require.Equal(t, cfg.DumpIOTotalBytes.Load(), uint64(200)) var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 10 { + wg.Go(func() { data, err := json.Marshal(cfg) require.NoError(t, err) - jsonMap := make(map[string]interface{}) + jsonMap := make(map[string]any) err = json.Unmarshal(data, &jsonMap) require.NoError(t, err) @@ -487,11 +485,9 @@ func TestSubTaskConfigMarshalAtomic(t *testing.T) { _, hasDumpUUID := jsonMap["dump-uuid"] require.False(t, hasUUID, "UUID should not be in JSON") require.False(t, hasDumpUUID, "DumpUUID should not be in JSON") - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { newCfg, err := cfg.Clone() require.NoError(t, err) @@ -501,14 +497,12 @@ func TestSubTaskConfigMarshalAtomic(t *testing.T) { require.GreaterOrEqual(t, newCfg.DumpIOTotalBytes.Load(), uint64(200)) require.Equal(t, newCfg.UUID, uuid) require.Equal(t, newCfg.DumpUUID, dumpUUID) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { cfg.IOTotalBytes.Add(1) cfg.DumpIOTotalBytes.Add(1) - }() + }) } wg.Wait() diff --git a/dm/config/task.go b/dm/config/task.go index acea793b62..413dd36076 100644 --- a/dm/config/task.go +++ b/dm/config/task.go @@ -230,7 +230,7 @@ func DefaultMydumperConfig() MydumperConfig { type rawMydumperConfig MydumperConfig // UnmarshalYAML implements Unmarshaler.UnmarshalYAML. -func (m *MydumperConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (m *MydumperConfig) UnmarshalYAML(unmarshal func(any) error) error { raw := rawMydumperConfig(DefaultMydumperConfig()) if err := unmarshal(&raw); err != nil { return terror.ErrConfigYamlTransform.Delegate(err, "unmarshal mydumper config") @@ -324,7 +324,7 @@ func DefaultLoaderConfig() LoaderConfig { type rawLoaderConfig LoaderConfig // UnmarshalYAML implements Unmarshaler.UnmarshalYAML. -func (m *LoaderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (m *LoaderConfig) UnmarshalYAML(unmarshal func(any) error) error { raw := rawLoaderConfig(DefaultLoaderConfig()) if err := unmarshal(&raw); err != nil { return terror.ErrConfigYamlTransform.Delegate(err, "unmarshal loader config") @@ -461,7 +461,7 @@ func DefaultSyncerConfig() SyncerConfig { type rawSyncerConfig SyncerConfig // UnmarshalYAML implements Unmarshaler.UnmarshalYAML. -func (m *SyncerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (m *SyncerConfig) UnmarshalYAML(unmarshal func(any) error) error { raw := rawSyncerConfig(DefaultSyncerConfig()) if err := unmarshal(&raw); err != nil { return terror.ErrConfigYamlTransform.Delegate(err, "unmarshal syncer config") @@ -1050,7 +1050,7 @@ func (c *TaskConfig) adjust() error { // getGenerateName generates name by rule or gets name from nameMap // if it's a new name, increase nameIdx // otherwise return current nameIdx. -func getGenerateName(rule interface{}, nameIdx int, namePrefix string, nameMap map[string]string) (string, int) { +func getGenerateName(rule any, nameIdx int, namePrefix string, nameMap map[string]string) (string, int) { // use json as key since no DeepEqual for rules now. ruleByte, err := json.Marshal(rule) if err != nil { diff --git a/dm/config/task_test.go b/dm/config/task_test.go index ffb034a180..72624cd8b0 100644 --- a/dm/config/task_test.go +++ b/dm/config/task_test.go @@ -53,7 +53,6 @@ func TestIsForeignKeyChecksEnabled(t *testing.T) { } for _, c := range cases { - c := c t.Run(c.name, func(t *testing.T) { t.Parallel() require.Equal(t, c.expected, IsForeignKeyChecksEnabled(c.session)) @@ -1114,7 +1113,7 @@ func TestTaskConfigForDowngrade(t *testing.T) { } // Clone clones src to dest. -func Clone(dest, src interface{}) { +func Clone(dest, src any) { cloneValues(reflect.ValueOf(dest), reflect.ValueOf(src)) } @@ -1123,17 +1122,17 @@ func Clone(dest, src interface{}) { func cloneValues(dest, src reflect.Value) { destType := dest.Type() srcType := src.Type() - if destType.Kind() == reflect.Ptr { + if destType.Kind() == reflect.Pointer { destType = destType.Elem() } - if srcType.Kind() == reflect.Ptr { + if srcType.Kind() == reflect.Pointer { srcType = srcType.Elem() } if destType.Kind() == reflect.Map { destMap := reflect.MakeMap(destType) for _, k := range src.MapKeys() { - if src.MapIndex(k).Type().Kind() == reflect.Ptr { + if src.MapIndex(k).Type().Kind() == reflect.Pointer { newVal := reflect.New(destType.Elem().Elem()) cloneValues(newVal, src.MapIndex(k)) destMap.SetMapIndex(k, newVal) @@ -1148,7 +1147,7 @@ func cloneValues(dest, src reflect.Value) { if destType.Kind() == reflect.Slice { slice := reflect.MakeSlice(destType, src.Len(), src.Cap()) for i := 0; i < src.Len(); i++ { - if slice.Index(i).Type().Kind() == reflect.Ptr { + if slice.Index(i).Type().Kind() == reflect.Pointer { newVal := reflect.New(slice.Index(i).Type().Elem()) cloneValues(newVal, src.Index(i)) slice.Index(i).Set(newVal) @@ -1170,10 +1169,10 @@ func cloneValues(dest, src reflect.Value) { srcField := src.Elem().Field(i) destFieldType := destField.Type() srcFieldType := srcField.Type() - if destFieldType.Kind() == reflect.Ptr { + if destFieldType.Kind() == reflect.Pointer { destFieldType = destFieldType.Elem() } - if srcFieldType.Kind() == reflect.Ptr { + if srcFieldType.Kind() == reflect.Pointer { srcFieldType = srcFieldType.Elem() } if destFieldType != srcFieldType { diff --git a/dm/ctl/common/config.go b/dm/ctl/common/config.go index 70a3225b6b..0d3a4aa05d 100644 --- a/dm/ctl/common/config.go +++ b/dm/ctl/common/config.go @@ -200,8 +200,8 @@ func (c *Config) adjust() error { // validate host:port format address. func validateAddr(addr string) error { - endpoints := strings.Split(addr, ",") - for _, endpoint := range endpoints { + endpoints := strings.SplitSeq(addr, ",") + for endpoint := range endpoints { if _, _, err := net.SplitHostPort(utils.UnwrapScheme(endpoint)); err != nil { return errors.Trace(err) } diff --git a/dm/ctl/common/util.go b/dm/ctl/common/util.go index daf593841b..5940857cfe 100644 --- a/dm/ctl/common/util.go +++ b/dm/ctl/common/util.go @@ -98,9 +98,9 @@ func (c *CtlClient) updateMasterClient() error { func (c *CtlClient) sendRequest( ctx context.Context, reqName string, - req interface{}, - respPointer interface{}, - opts ...interface{}, + req any, + respPointer any, + opts ...any, ) error { c.mu.RLock() defer c.mu.RUnlock() @@ -121,12 +121,12 @@ func (c *CtlClient) sendRequest( } // SendRequest send request to master. -func SendRequest(ctx context.Context, reqName string, req interface{}, respPointer interface{}) error { +func SendRequest(ctx context.Context, reqName string, req any, respPointer any) error { err := GlobalCtlClient.sendRequest(ctx, reqName, req, respPointer) if err == nil { return nil } - var opts []interface{} + var opts []any switch status.Code(err) { case codes.ResourceExhausted: matches := re.FindStringSubmatch(err.Error()) @@ -199,7 +199,7 @@ func GlobalConfig() *Config { } // PrintLinesf adds a wrap to support `\n` within `chzyer/readline`. -func PrintLinesf(format string, a ...interface{}) { +func PrintLinesf(format string, a ...any) { fmt.Println(fmt.Sprintf(format, a...)) } @@ -214,7 +214,7 @@ func PrettyPrintResponse(resp proto.Message) { } // PrettyPrintInterface prints an interface through encoding/json prettily. -func PrettyPrintInterface(resp interface{}) { +func PrettyPrintInterface(resp any) { s, err := json.MarshalIndent(resp, "", " ") if err != nil { PrintLinesf("%v", err) diff --git a/dm/ctl/master/operate_task.go b/dm/ctl/master/operate_task.go index 4fb37366ca..e72e62abd4 100644 --- a/dm/ctl/master/operate_task.go +++ b/dm/ctl/master/operate_task.go @@ -126,9 +126,7 @@ func batchOperateTask(taskOp pb.TaskOp, batchSize int, sources []string, subTask var wg sync.WaitGroup resultCh := make(chan *operateTaskResult, 1) for i := 0; i < batchSize; i++ { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for name := range workCh { taskResult := operateTaskResult{Task: name, Op: taskOp.String()} @@ -143,7 +141,7 @@ func batchOperateTask(taskOp pb.TaskOp, batchSize int, sources []string, subTask } resultCh <- &taskResult } - }() + }) } go func() { diff --git a/dm/dumpling/dumpling.go b/dm/dumpling/dumpling.go index 5d8540a5af..4ac0c86db3 100644 --- a/dm/dumpling/dumpling.go +++ b/dm/dumpling/dumpling.go @@ -270,7 +270,7 @@ func (m *Dumpling) Update(context.Context, *config.SubTaskConfig) error { } // Status implements Unit.Status. -func (m *Dumpling) Status(_ *binlog.SourceStatus) interface{} { +func (m *Dumpling) Status(_ *binlog.SourceStatus) any { // NOTE: try to add some status, like dumped file count m.mu.RLock() defer m.mu.RUnlock() @@ -369,7 +369,7 @@ func (m *Dumpling) constructArgs(ctx context.Context) (*export.Config, error) { return nil, err1 } } - dumpConfig.SessionParams = map[string]interface{}{ + dumpConfig.SessionParams = map[string]any{ "time_zone": tz, } diff --git a/dm/loader/checkpoint.go b/dm/loader/checkpoint.go index a103d8609a..18abbbbbfa 100644 --- a/dm/loader/checkpoint.go +++ b/dm/loader/checkpoint.go @@ -123,7 +123,7 @@ func (cp *LightningCheckpointList) RegisterCheckPoint(ctx context.Context) error cp.logger.Info("initial checkpoint record", zap.String("task", cp.taskName), zap.String("source", cp.sourceName)) - args := []interface{}{cp.taskName, cp.sourceName} + args := []any{cp.taskName, cp.sourceName} tctx := tcontext.NewContext(ctx, log.With(zap.String("job", "lightning-checkpoint"))) _, err = connection.ExecuteSQL(tctx, nil, "lightning-checkpoint", []string{sql}, args) if err != nil { @@ -145,7 +145,7 @@ func (cp *LightningCheckpointList) UpdateStatus(ctx context.Context, status ligh zap.Stringer("status", status)) tctx := tcontext.NewContext(ctx, log.With(zap.String("job", "lightning-checkpoint"))) _, err = connection.ExecuteSQL(tctx, nil, "lightning-checkpoint", []string{sql}, - []interface{}{status.String(), cp.taskName, cp.sourceName}) + []any{status.String(), cp.taskName, cp.sourceName}) if err != nil { return terror.WithScope(terror.Annotate(err, "update lightning status"), terror.ScopeDownstream) } diff --git a/dm/loader/lightning.go b/dm/loader/lightning.go index 500b9ebf45..49cbb19e34 100644 --- a/dm/loader/lightning.go +++ b/dm/loader/lightning.go @@ -16,6 +16,7 @@ package loader import ( "context" "fmt" + "maps" "path/filepath" "regexp" "strings" @@ -307,8 +308,8 @@ func (l *LightningLoader) runLightning(ctx context.Context, cfg *lcfg.Config) (e failpoint.Inject("LoadDataSlowDown", nil) failpoint.Inject("LoadDataSlowDownByTask", func(val failpoint.Value) { tasks := val.(string) - taskNames := strings.Split(tasks, ",") - for _, taskName := range taskNames { + taskNames := strings.SplitSeq(tasks, ",") + for taskName := range taskNames { if l.cfg.Name == taskName { l.logger.Info("inject failpoint LoadDataSlowDownByTask in lightning loader", zap.String("task", taskName)) <-taskCtx.Done() @@ -463,9 +464,7 @@ func GetLightningConfig(globalCfg *lcfg.GlobalConfig, subtaskCfg *config.SubTask cfg.TiDB.Vars = make(map[string]string) cfg.Routes = subtaskCfg.RouteRules if subtaskCfg.To.Session != nil { - for k, v := range subtaskCfg.To.Session { - cfg.TiDB.Vars[k] = v - } + maps.Copy(cfg.TiDB.Vars, subtaskCfg.To.Session) } if subtaskCfg.RangeConcurrency > 0 { @@ -727,7 +726,7 @@ func (l *LightningLoader) status() *pb.LoadStatus { } // Status returns the unit's current status. -func (l *LightningLoader) Status(_ *binlog.SourceStatus) interface{} { +func (l *LightningLoader) Status(_ *binlog.SourceStatus) any { return l.status() } diff --git a/dm/master/agent_pool.go b/dm/master/agent_pool.go index 3b21e22acb..10ef0e4b03 100644 --- a/dm/master/agent_pool.go +++ b/dm/master/agent_pool.go @@ -29,7 +29,7 @@ const ( ErrorNoEmitToken = "fail to get emit opportunity for %s" ) -type emitFunc func(args ...interface{}) +type emitFunc func(args ...any) // AgentPool is a pool to control communication with dm-workers // It provides rate limit control for agent acquire, including dispatch rate r @@ -108,7 +108,7 @@ func (ap *AgentPool) Start(ctx context.Context) { } // Emit applies for an agent to communicates with dm-worker. -func (ap *AgentPool) Emit(ctx context.Context, id int, fn emitFunc, errFn emitFunc, args ...interface{}) { +func (ap *AgentPool) Emit(ctx context.Context, id int, fn emitFunc, errFn emitFunc, args ...any) { if agent := ap.Apply(ctx, id); agent == nil { errFn(args...) } else { diff --git a/dm/master/agent_pool_test.go b/dm/master/agent_pool_test.go index b4d1d2bb57..dc86b6009a 100644 --- a/dm/master/agent_pool_test.go +++ b/dm/master/agent_pool_test.go @@ -41,7 +41,7 @@ func (t *testMaster) testPool(c *check.C) { } }() - for i := 0; i < burst; i++ { + for i := range burst { agent := <-pc c.Assert(agent.ID, check.Equals, i) } @@ -51,7 +51,7 @@ func (t *testMaster) testPool(c *check.C) { default: } - for i := 0; i < rate; i++ { + for i := range rate { select { case agent := <-pc: c.Assert(agent.ID, check.Equals, i+burst) @@ -73,7 +73,7 @@ func (t *testMaster) testEmit(c *check.C) { ap := NewAgentPool(&RateLimitConfig{rate: DefaultRate, burst: DefaultBurst}) go ap.Start(context.Background()) - ap.Emit(context.Background(), 1, func(args ...interface{}) { + ap.Emit(context.Background(), 1, func(args ...any) { if len(args) != 2 { c.Fatalf("args count is not 2, args %v", args) } @@ -93,14 +93,14 @@ func (t *testMaster) testEmit(c *check.C) { if worker1 != worker { c.Fatalf("args[1] is not expected worker, args[1] %v vs %v", worker1, worker) } - }, func(args ...interface{}) {}, []interface{}{id, worker}...) + }, func(args ...any) {}, []any{id, worker}...) counter := 0 ctx, cancel := context.WithCancel(context.Background()) cancel() - ap.Emit(ctx, 1, func(args ...interface{}) { + ap.Emit(ctx, 1, func(args ...any) { c.FailNow() - }, func(args ...interface{}) { + }, func(args ...any) { if len(args) != 1 { c.Fatalf("args count is not 1, args %v", args) } @@ -109,6 +109,6 @@ func (t *testMaster) testEmit(c *check.C) { c.Fatalf("args[0] is not *int, args %+v", args) } *pCounter++ - }, []interface{}{&counter}...) + }, []any{&counter}...) c.Assert(counter, check.Equals, 1) } diff --git a/dm/master/bootstrap_test.go b/dm/master/bootstrap_test.go index eedc1cfb4e..a4f05b6f65 100644 --- a/dm/master/bootstrap_test.go +++ b/dm/master/bootstrap_test.go @@ -142,7 +142,7 @@ func (t *testMaster) TestCollectSourceConfigFilesV1Import(c *check.C) { c.Assert(err, check.IsNil) // fix empty map after marshal/unmarshal becomes nil cfg1.From.Adjust() - cfg1.Tracer = map[string]interface{}{} + cfg1.Tracer = map[string]any{} cfg1.Filters = []*filter.BinlogEventRule{} cfg1.From.Host = host cfg1.From.Port = port diff --git a/dm/master/etcd_test.go b/dm/master/etcd_test.go index 2987612e33..cc771ff3b6 100644 --- a/dm/master/etcd_test.go +++ b/dm/master/etcd_test.go @@ -188,7 +188,7 @@ func (t *testEtcdSuite) TestPrepareJoinEtcd(c *check.C) { defer e2.Close() // try join again - for i := 0; i < 20; i++ { + for range 20 { err = prepareJoinEtcd(cfgAfter2) if err == nil { break @@ -242,7 +242,7 @@ func (t *testEtcdSuite) TestEtcdAutoCompaction(c *check.C) { }) c.Assert(err, check.IsNil) - for i := 0; i < 100; i++ { + for i := range 100 { _, err = etcdCli.Put(ctx, "key", fmt.Sprintf("%03d", i)) c.Assert(err, check.IsNil) } diff --git a/dm/master/openapi_view_test.go b/dm/master/openapi_view_test.go index 330ec908f3..c22f1d80d1 100644 --- a/dm/master/openapi_view_test.go +++ b/dm/master/openapi_view_test.go @@ -252,7 +252,7 @@ func (s *OpenAPIViewSuite) TestClusterAPI() { // offline master-2 with retry // operate etcd cluster may met `etcdserver: unhealthy cluster`, add some retry - for i := 0; i < 20; i++ { + for range 20 { result = testutil.NewRequest().Delete(fmt.Sprintf("%s/%s", masterURL, s2.cfg.Name)).GoWithHTTPHandler(s.T(), s1.openapiHandles) if result.Code() == http.StatusBadRequest { s.Equal(http.StatusBadRequest, result.Code()) diff --git a/dm/master/scheduler/latch_test.go b/dm/master/scheduler/latch_test.go index 6ed0366ddb..58aa29ffa3 100644 --- a/dm/master/scheduler/latch_test.go +++ b/dm/master/scheduler/latch_test.go @@ -35,7 +35,7 @@ func TestOneAcquireSuccess(t *testing.T) { wg sync.WaitGroup ) - for i := 0; i < 10; i++ { + for i := range 10 { var group string if i < 5 { group = group1 @@ -56,7 +56,7 @@ func TestOneAcquireSuccess(t *testing.T) { }(group) } - for i := 0; i < 10; i++ { + for range 10 { fire <- struct{}{} } wg.Wait() @@ -81,10 +81,8 @@ func TestAcquireAfterRelease(t *testing.T) { wg sync.WaitGroup ) - for i := 0; i < 5; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 5 { + wg.Go(func() { <-fire for { @@ -98,10 +96,10 @@ func TestAcquireAfterRelease(t *testing.T) { return } } - }() + }) } - for i := 0; i < 5; i++ { + for range 5 { fire <- struct{}{} } @@ -119,7 +117,7 @@ func TestMultiRelease(t *testing.T) { wg sync.WaitGroup ) - for repeat := 0; repeat < 3; repeat++ { + for range 3 { for i := range names { wg.Add(1) go func(name string) { diff --git a/dm/master/scheduler/scheduler.go b/dm/master/scheduler/scheduler.go index c53a5fbb1c..68a790148f 100644 --- a/dm/master/scheduler/scheduler.go +++ b/dm/master/scheduler/scheduler.go @@ -15,6 +15,7 @@ package scheduler import ( "context" + "maps" "sort" "sync" "time" @@ -456,7 +457,7 @@ func (s *Scheduler) RemoveSourceCfg(source string) error { // 2. check whether any subtask or relay config exists for the source. existingSubtasksM := make(map[string]struct{}) - s.subTaskCfgs.Range(func(k, v interface{}) bool { + s.subTaskCfgs.Range(func(k, v any) bool { task := k.(string) cfg := v.(map[string]config.SubTaskConfig) for source2 := range cfg { @@ -785,7 +786,7 @@ func (s *Scheduler) BatchOperateTaskOnWorker( } // wait all tasks are in expected stage before actually starting scheduling WaitLoop: - for retry := 0; retry < maxQueryWorkerRetryNum; retry++ { + for retry := range maxQueryWorkerRetryNum { resp, err := worker.queryStatus(ctx) if err != nil { return terror.Annotatef(err, "failed to query worker: %s status", worker.baseInfo.Name) @@ -1173,7 +1174,7 @@ func (s *Scheduler) GetSubTaskCfgsByTaskAndSource(taskName string, sources []str } // filter the source that we don't want if len(sources) > 0 { - filterSource := map[string]interface{}{} + filterSource := map[string]any{} for _, source := range sources { filterSource[source] = true // the source we want } @@ -1195,7 +1196,7 @@ func (s *Scheduler) GetSubTaskCfgsByTaskAndSource(taskName string, sources []str func (s *Scheduler) GetSubTaskCfgs() map[string]map[string]config.SubTaskConfig { // taskName -> sourceName -> SubTaskConfig clone := make(map[string]map[string]config.SubTaskConfig) - s.subTaskCfgs.Range(func(k, v interface{}) bool { + s.subTaskCfgs.Range(func(k, v any) bool { task := k.(string) m := v.(map[string]config.SubTaskConfig) clone2 := make(map[string]config.SubTaskConfig, len(m)) @@ -1218,7 +1219,7 @@ func (s *Scheduler) GetALlSubTaskCfgs() map[string]map[string]*config.SubTaskCon defer s.mu.RUnlock() // taskName -> sourceName -> SubTaskConfig clone := make(map[string]map[string]*config.SubTaskConfig) - s.subTaskCfgs.Range(func(k, v interface{}) bool { + s.subTaskCfgs.Range(func(k, v any) bool { task := k.(string) m := v.(map[string]config.SubTaskConfig) clone2 := make(map[string]*config.SubTaskConfig, len(m)) @@ -1238,7 +1239,7 @@ func (s *Scheduler) GetALlSubTaskCfgs() map[string]map[string]*config.SubTaskCon // GetTaskNameListBySourceName gets task name list by source name. func (s *Scheduler) GetTaskNameListBySourceName(sourceName string, expectStage *pb.Stage) []string { var taskNameList []string - s.expectSubTaskStages.Range(func(k, v interface{}) bool { + s.expectSubTaskStages.Range(func(k, v any) bool { subtaskM := v.(map[string]ha.Stage) subtaskStage, ok2 := subtaskM[sourceName] if !ok2 { @@ -1805,12 +1806,8 @@ func (s *Scheduler) recoverSources() error { } // recover in-memory data. - for source, cfg := range cfgM { - s.sourceCfgs[source] = cfg - } - for source, stage := range stageM { - s.expectRelayStages[source] = stage - } + maps.Copy(s.sourceCfgs, cfgM) + maps.Copy(s.expectRelayStages, stageM) return nil } diff --git a/dm/master/scheduler/scheduler_test.go b/dm/master/scheduler/scheduler_test.go index 3a95da06f2..aff7750e5d 100644 --- a/dm/master/scheduler/scheduler_test.go +++ b/dm/master/scheduler/scheduler_test.go @@ -207,11 +207,9 @@ func (t *testSchedulerSuite) testSchedulerProgress(restart int) { // do keep-alive for worker1. ctx1, cancel1 := context.WithCancel(ctx) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx1, t.etcdTestCli, workerName1, keepAliveTTL)) - }() + }) // wait for source1 being bound to worker1. require.Eventually(t.T(), func() bool { bounds := s.BoundSources() @@ -334,11 +332,9 @@ func (t *testSchedulerSuite) testSchedulerProgress(restart int) { // CASE 3.2: start worker1 again. // do keep-alive for worker1 again. ctx1, cancel1 = context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx1, t.etcdTestCli, workerName1, keepAliveTTL)) - }() + }) // wait for source1 bound to worker1. require.Eventually(t.T(), func() bool { bounds := s.BoundSources() @@ -379,11 +375,9 @@ func (t *testSchedulerSuite) testSchedulerProgress(restart int) { // CASE 4.3: the worker2 become online. // do keep-alive for worker2. ctx2, cancel2 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx2, t.etcdTestCli, workerName2, keepAliveTTL)) - }() + }) // wait for worker2 become Free. require.Eventually(t.T(), func() bool { w := s.GetWorkerByName(workerName2) @@ -859,11 +853,9 @@ func (t *testSchedulerSuite) TestRestartScheduler() { }() // step 2.2: worker start keepAlive ctx1, cancel1 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx1, t.etcdTestCli, workerName1, keepAliveTTL)) - }() + }) // step 2.3: scheduler should bound source to worker // wait for source1 bound to worker1. require.Eventually(t.T(), func() bool { @@ -898,11 +890,9 @@ func (t *testSchedulerSuite) TestRestartScheduler() { require.Len(t.T(), sourceBoundCh, 0) ctx2, cancel2 := context.WithCancel(ctx) // trigger same keepalive event again, just for test - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx2, t.etcdTestCli, workerName1, keepAliveTTL)) - }() + }) checkSourceBoundCh() // case 3: scheduler is restarted, but worker also broke after scheduler is down // step 5: stop scheduler -> stop worker keepalive -> restart scheduler @@ -934,11 +924,9 @@ func (t *testSchedulerSuite) TestRestartScheduler() { // first let the source bound again ctx4, cancel4 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx4, t.etcdTestCli, workerName1, keepAliveTTL)) - }() + }) sourceBound1.Source = sourceID1 sourceBound1.IsDeleted = false checkSourceBoundCh() @@ -1026,16 +1014,12 @@ func (t *testSchedulerSuite) TestWatchWorkerEventEtcdCompact() { // step 3: add two workers, and then cancel them to simulate they have lost connection var wg sync.WaitGroup ctx1, cancel1 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx1, t.etcdTestCli, workerName1, keepAliveTTL)) - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx1, t.etcdTestCli, workerName2, keepAliveTTL)) - }() + }) require.Eventually(t.T(), func() bool { kam, _, e := ha.GetKeepAliveWorkers(t.etcdTestCli) return e == nil && len(kam) == 2 @@ -1068,11 +1052,9 @@ func (t *testSchedulerSuite) TestWatchWorkerEventEtcdCompact() { // step 5: scheduler start to handle workerEvent from compact revision, should handle worker keepalive events correctly ctx2, cancel2 := context.WithCancel(ctx) // step 5.1: start one worker before scheduler start to handle workerEvent - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx2, t.etcdTestCli, workerName3, keepAliveTTL)) - }() + }) require.Eventually(t.T(), func() bool { kam, _, err := ha.GetKeepAliveWorkers(t.etcdTestCli) if err == nil { @@ -1083,18 +1065,14 @@ func (t *testSchedulerSuite) TestWatchWorkerEventEtcdCompact() { return false }, 3*time.Second, 100*time.Millisecond) // step 5.2: scheduler start to handle workerEvent - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), s.observeWorkerEvent(ctx2, startRev)) - }() + }) // step 5.3: wait for scheduler to restart handleWorkerEvent, then start a new worker time.Sleep(time.Second) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), ha.KeepAlive(ctx2, t.etcdTestCli, workerName4, keepAliveTTL)) - }() + }) require.Eventually(t.T(), func() bool { unbounds := s.UnboundSources() return len(unbounds) == 0 @@ -1105,11 +1083,9 @@ func (t *testSchedulerSuite) TestWatchWorkerEventEtcdCompact() { // step 6: restart to observe workerEvents, should unbound all sources ctx3, cancel3 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), s.observeWorkerEvent(ctx3, startRev)) - }() + }) require.Eventually(t.T(), func() bool { bounds := s.BoundSources() return len(bounds) == 0 @@ -1804,11 +1780,9 @@ func (t *testSchedulerSuite) TestWatchLoadTask() { require.True(t.T(), s.hasLoadTaskByWorkerAndSource(workerName4, sourceID2)) // observer load tasks - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), s.observeLoadTask(ctx1, startRev)) - }() + }) // put task2, source1, worker1 _, err = ha.PutLoadTask(t.etcdTestCli, task2, sourceID1, workerName1) diff --git a/dm/master/server.go b/dm/master/server.go index 9c0950798d..2d8cb6590f 100644 --- a/dm/master/server.go +++ b/dm/master/server.go @@ -22,6 +22,7 @@ import ( "net/http" "reflect" "runtime" + "slices" "sort" "strings" "sync" @@ -254,24 +255,18 @@ func (s *Server) Start(ctx context.Context) (err error) { s.closed.Store(false) // the server started now. - s.bgFunWg.Add(1) - go func() { - defer s.bgFunWg.Done() + s.bgFunWg.Go(func() { s.ap.Start(ctx) - }() + }) - s.bgFunWg.Add(1) - go func() { - defer s.bgFunWg.Done() + s.bgFunWg.Go(func() { s.electionNotify(ctx) - }() + }) runBackgroundOnce.Do(func() { - s.bgFunWg.Add(1) - go func() { - defer s.bgFunWg.Done() + s.bgFunWg.Go(func() { metrics.RunBackgroundJob(ctx) - }() + }) }) failpoint.Inject("FailToElect", func(val failpoint.Value) { @@ -484,7 +479,7 @@ func (s *Server) StartTask(ctx context.Context, req *pb.StartTaskRequest) (*pb.S var b strings.Builder size := 5 * 1024 * 1024 b.Grow(size) - for i := 0; i < size; i++ { + for range size { b.WriteByte(0) } resp2 = &pb.StartTaskResponse{Msg: b.String()} @@ -845,12 +840,7 @@ func (s *Server) QueryStatus(ctx context.Context, req *pb.QueryStatusListRequest resps := s.getStatusFromWorkers(ctx, sources, req.Name, specifiedSource) workerRespMap := make(map[string][]*pb.QueryStatusResponse, len(sources)) // sourceName -> worker QueryStatusResponse inSlice := func(s []string, e string) bool { - for _, v := range s { - if v == e { - return true - } - } - return false + return slices.Contains(s, e) } for _, workerResp := range resps { workerRespMap[workerResp.SourceStatus.Source] = append(workerRespMap[workerResp.SourceStatus.Source], workerResp) @@ -1190,7 +1180,7 @@ func (s *Server) getStatusFromWorkers( for _, worker := range workers { wg.Add(1) - go s.ap.Emit(ctx, 0, func(args ...interface{}) { + go s.ap.Emit(ctx, 0, func(args ...any) { defer wg.Done() sourceID := args[0].(string) w, _ := args[1].(*scheduler.Worker) @@ -1214,7 +1204,7 @@ func (s *Server) getStatusFromWorkers( } workerStatus.SourceStatus.Source = sourceID setWorkerResp(workerStatus) - }, func(args ...interface{}) { + }, func(args ...any) { defer wg.Done() sourceID, _ := args[0].(string) w, _ := args[1].(*scheduler.Worker) @@ -1932,7 +1922,7 @@ func (s *Server) waitOperationOk( cli *scheduler.Worker, taskName string, sourceID string, - masterReq interface{}, + masterReq any, ) (bool, string, *pb.QueryStatusResponse, error) { var expect pb.Stage switch req := masterReq.(type) { @@ -2121,7 +2111,7 @@ func (s *Server) waitOperationOk( return false, "", nil, terror.ErrMasterFailToGetExpectResult } -func (s *Server) handleOperationResult(ctx context.Context, cli *scheduler.Worker, taskName, sourceID string, req interface{}) *pb.CommonWorkerResponse { +func (s *Server) handleOperationResult(ctx context.Context, cli *scheduler.Worker, taskName, sourceID string, req any) *pb.CommonWorkerResponse { if cli == nil { return errorCommonWorkerResponse(sourceID+" relevant worker-client not found", sourceID, "") } @@ -2152,7 +2142,7 @@ func sortCommonWorkerResults(sourceRespCh chan *pb.CommonWorkerResponse) []*pb.C return sourceResps } -func (s *Server) getSourceRespsAfterOperation(ctx context.Context, taskName string, sources, workers []string, req interface{}) []*pb.CommonWorkerResponse { +func (s *Server) getSourceRespsAfterOperation(ctx context.Context, taskName string, sources, workers []string, req any) []*pb.CommonWorkerResponse { sourceRespCh := make(chan *pb.CommonWorkerResponse, len(sources)) var wg sync.WaitGroup for i, source := range sources { @@ -2161,7 +2151,7 @@ func (s *Server) getSourceRespsAfterOperation(ctx context.Context, taskName stri if i < len(workers) { worker = workers[i] } - go s.ap.Emit(ctx, 0, func(args ...interface{}) { + go s.ap.Emit(ctx, 0, func(args ...any) { defer wg.Done() source1, _ := args[0].(string) worker1, _ := args[1].(string) @@ -2175,7 +2165,7 @@ func (s *Server) getSourceRespsAfterOperation(ctx context.Context, taskName stri sourceResp := s.handleOperationResult(ctx, workerCli, taskName, source1, req) sourceResp.Source = source1 // may return other source's ID during stop worker sourceRespCh <- sourceResp - }, func(args ...interface{}) { + }, func(args ...any) { defer wg.Done() source1, _ := args[0].(string) worker1, _ := args[1].(string) @@ -2795,7 +2785,7 @@ func (s *Server) OperateRelay(ctx context.Context, req *pb.OperateRelayRequest) // sharedLogic does some shared logic for each RPC implementation // arguments with `Pointer` suffix should be pointer to that variable its name indicated // return `true` means caller should return with variable that `xxPointer` modified. -func (s *Server) sharedLogic(ctx context.Context, req interface{}, respPointer interface{}, errPointer *error) bool { +func (s *Server) sharedLogic(ctx context.Context, req any, respPointer any, errPointer *error) bool { // nolint:dogsled pc, _, _, _ := runtime.Caller(1) fullMethodName := runtime.FuncForPC(pc).Name() @@ -3234,7 +3224,7 @@ func sendValidationRequest[T any]( return } wg.Add(1) - go s.ap.Emit(ctx, 0, func(args ...interface{}) { + go s.ap.Emit(ctx, 0, func(args ...any) { // send request in parallel defer wg.Done() workerResp, err := worker.SendRequest(ctx, req, s.cfg.RPCTimeout) @@ -3245,7 +3235,7 @@ func sendValidationRequest[T any]( resp := getValidationWorkerResp(req, workerResp) appendWorkerResp(workerRespMu, workerResps, resp.(T)) } - }, func(args ...interface{}) { + }, func(args ...any) { defer wg.Done() err := terror.ErrMasterNoEmitToken.Generate(sourceID) resp := genValidationWorkerErrorResp(req, err, logMsg, worker.BaseInfo().Name, sourceID) @@ -3253,7 +3243,7 @@ func sendValidationRequest[T any]( }) } -func getValidationWorkerResp(req *workerrpc.Request, resp *workerrpc.Response) interface{} { +func getValidationWorkerResp(req *workerrpc.Request, resp *workerrpc.Response) any { switch req.Type { case workerrpc.CmdGetValidationStatus: return resp.GetValidationStatus @@ -3266,7 +3256,7 @@ func getValidationWorkerResp(req *workerrpc.Request, resp *workerrpc.Response) i } } -func genValidationWorkerErrorResp(req *workerrpc.Request, err error, logMsg, workerID, sourceID string) interface{} { +func genValidationWorkerErrorResp(req *workerrpc.Request, err error, logMsg, workerID, sourceID string) any { log.L().Error(logMsg, zap.Error(err), zap.String("source", sourceID), zap.String("worker", workerID)) switch req.Type { case workerrpc.CmdGetValidationStatus: diff --git a/dm/master/server_test.go b/dm/master/server_test.go index 741f36c38f..a432a4cde7 100644 --- a/dm/master/server_test.go +++ b/dm/master/server_test.go @@ -213,7 +213,7 @@ func stageDeepEqualExcludeRev(t *testing.T, stage, expectStage ha.Stage) { require.Equal(t, expectStage, stage) } -func mockRevelantWorkerClient(mockWorkerClient *pbmock.MockWorkerClient, taskName, sourceID string, masterReq interface{}) { +func mockRevelantWorkerClient(mockWorkerClient *pbmock.MockWorkerClient, taskName, sourceID string, masterReq any) { var expect pb.Stage switch req := masterReq.(type) { case *pb.OperateSourceRequest: @@ -313,7 +313,7 @@ func makeNilWorkerClients(workers []string) map[string]workerrpc.Client { return nilWorkerClients } -func makeWorkerClientsForHandle(ctrl *gomock.Controller, taskName string, sources []string, workers []string, reqs ...interface{}) map[string]workerrpc.Client { +func makeWorkerClientsForHandle(ctrl *gomock.Controller, taskName string, sources []string, workers []string, reqs ...any) map[string]workerrpc.Client { workerClients := make(map[string]workerrpc.Client, len(workers)) for i := range workers { mockWorkerClient := pbmock.NewMockWorkerClient(ctrl) @@ -517,7 +517,7 @@ func (t *testMasterSuite) TestQueryStatus() { func (t *testMasterSuite) TestWaitOperationOkRightResult() { cases := []struct { - req interface{} + req any resp *pb.QueryStatusResponse expectedOK bool expectedEmptyMsg bool @@ -1004,9 +1004,7 @@ func (t *testMasterSuite) TestStartTaskWithRemoveMeta() { require.Greater(t.T(), len(server.pessimist.Locks()), 0) resp, err := server.StartTask(context.Background(), req) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { time.Sleep(10 * time.Microsecond) // start another same task at the same time, should get err verMock2 := conn.InitVersionDB() @@ -1017,7 +1015,7 @@ func (t *testMasterSuite) TestStartTaskWithRemoveMeta() { require.False(t.T(), resp1.Result) require.Equal(t.T(), terror.Annotate(terror.ErrSchedulerSubTaskExist.Generate(cfg.Name, sources), "while remove-meta is true").Error(), resp1.Msg) - }() + }) require.NoError(t.T(), err) require.True(t.T(), resp.Result, "start task failed: %s", resp.Msg) for _, source := range sources { @@ -1099,9 +1097,7 @@ func (t *testMasterSuite) TestStartTaskWithRemoveMeta() { require.Greater(t.T(), len(server.optimist.Locks()), 0) resp, err = server.StartTask(context.Background(), req) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { time.Sleep(10 * time.Microsecond) // start another same task at the same time, should get err vermock2 := conn.InitVersionDB() @@ -1112,7 +1108,7 @@ func (t *testMasterSuite) TestStartTaskWithRemoveMeta() { require.False(t.T(), resp1.Result) require.Equal(t.T(), terror.Annotate(terror.ErrSchedulerSubTaskExist.Generate(cfg.Name, sources), "while remove-meta is true").Error(), resp1.Msg) - }() + }) require.NoError(t.T(), err) require.True(t.T(), resp.Result) for _, source := range sources { @@ -1248,12 +1244,12 @@ func (t *testMasterSuite) TestPurgeWorkerRelay() { // mock PurgeRelay request mockPurgeRelay := func(rpcSuccess bool) { for i, worker := range workers { - rets := []interface{}{ + rets := []any{ nil, errors.New(errGRPCFailed), } if rpcSuccess { - rets = []interface{}{ + rets = []any{ &pb.CommonWorkerResponse{ Result: true, Source: sources[i], @@ -1926,22 +1922,18 @@ func (t *testMasterSuite) TestOfflineMember() { cancel() s1.Close() }() - wg.Add(1) - go func() { + wg.Go(func() { require.NoError(t.T(), s1.Start(ctx)) - wg.Done() - }() + }) s2 := NewServer(cfg2) defer func() { cancel() s2.Close() }() - wg.Add(1) - go func() { + wg.Go(func() { require.NoError(t.T(), s2.Start(ctx)) - wg.Done() - }() + }) ctx3, cancel3 := context.WithCancel(ctx) s3 := NewServer(cfg3) diff --git a/dm/master/shardddl/optimist.go b/dm/master/shardddl/optimist.go index cad7b258f2..47605d334f 100644 --- a/dm/master/shardddl/optimist.go +++ b/dm/master/shardddl/optimist.go @@ -81,13 +81,11 @@ func (o *Optimist) Start(pCtx context.Context, etcdCli *clientv3.Client) error { ctx, cancel := context.WithCancel(pCtx) - o.wg.Add(1) - go func() { - defer o.wg.Done() + o.wg.Go(func() { // TODO: handle fatal error from run //nolint:errcheck o.run(ctx, revSource, revInfo, revOperation) - }() + }) o.closed = false // started now, no error will interrupt the start process. o.cancel = cancel diff --git a/dm/master/shardddl/pessimist.go b/dm/master/shardddl/pessimist.go index f89b376eed..2a06f11b9b 100644 --- a/dm/master/shardddl/pessimist.go +++ b/dm/master/shardddl/pessimist.go @@ -83,13 +83,11 @@ func (p *Pessimist) Start(pCtx context.Context, etcdCli *clientv3.Client) error return err } ctx, cancel := context.WithCancel(pCtx) - p.wg.Add(1) - go func() { - defer p.wg.Done() + p.wg.Go(func() { // TODO: handle fatal error from run //nolint:errcheck p.run(ctx, etcdCli, rev1, rev2) - }() + }) p.closed = false // started now. p.cancel = cancel diff --git a/dm/master/shardddl/pessimist_test.go b/dm/master/shardddl/pessimist_test.go index 17ccdeca1c..e4d912e7e3 100644 --- a/dm/master/shardddl/pessimist_test.go +++ b/dm/master/shardddl/pessimist_test.go @@ -404,9 +404,7 @@ func (t *testPessimistSuite) TestSourceReEntrant() { // 4. wait exec operation for the owner become available. var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { opCh := make(chan pessimism.Operation, 10) errCh := make(chan error, 10) ctx2, cancel2 := context.WithTimeout(ctx, watchTimeout) @@ -419,7 +417,7 @@ func (t *testPessimistSuite) TestSourceReEntrant() { op := <-opCh require.True(t.T(), op.Exec) require.False(t.T(), op.Done) - }() + }) // 5. put i13, the lock will become synced, then an operation PUT for the owner will be triggered. _, err = pessimism.PutInfo(t.etcdTestCli, i13) @@ -445,9 +443,7 @@ func (t *testPessimistSuite) TestSourceReEntrant() { require.False(t.T(), op11.Done) // 9. wait exec operation for the non-owner become available. - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { opCh = make(chan pessimism.Operation, 10) errCh = make(chan error, 10) ctx2, cancel2 = context.WithTimeout(ctx, watchTimeout) @@ -460,7 +456,7 @@ func (t *testPessimistSuite) TestSourceReEntrant() { op := <-opCh require.False(t.T(), op.Exec) require.False(t.T(), op.Done) - }() + }) // 10. mark exec operation for the owner as `done` (and delete the info). op11c := op11 @@ -815,11 +811,9 @@ func (t *testPessimistSuite) TestUnlockSourceOwnerRemoved() { // 4. put done for the replace owner then can unlock the lock. var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { t.putDoneForSource(ctx, task, source2, i11, true, rev1+1, watchTimeout) - }() + }) require.NoError(t.T(), p.UnlockLock(ctx, ID, source2, false)) wg.Wait() @@ -908,15 +902,13 @@ func (t *testPessimistSuite) TestMeetEtcdCompactError() { // step 2: start running, i11 and i12 should be handled successfully ctx2, cancel2 := context.WithCancel(ctx) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { rev1, rev2 := revCompacted, revThreshold if i == 1 { rev1, rev2 = rev2, rev1 } require.NoError(t.T(), p.run(ctx2, t.etcdTestCli, rev1, rev2)) - }() + }) // PUT i11, will create a lock but not synced. require.Eventually(t.T(), func() bool { return len(p.Locks()) == 1 diff --git a/dm/pkg/backoff/backoff_test.go b/dm/pkg/backoff/backoff_test.go index 46c56b064f..7d006a9a3b 100644 --- a/dm/pkg/backoff/backoff_test.go +++ b/dm/pkg/backoff/backoff_test.go @@ -70,14 +70,14 @@ func TestExponentialBackoff(t *testing.T) { Factor: factor, } - for i := 0; i < 10; i++ { + for i := range 10 { expected := minT * time.Duration(math.Pow(factor, float64(i))) require.Equal(t, expected, b.Duration()) } b.Rollback() require.Equal(t, 512*minT, b.Current()) b.Forward() - for i := 0; i < 10; i++ { + for range 10 { require.Equal(t, maxT, b.Duration()) } b.Reset() @@ -123,7 +123,7 @@ func TestFixedBackoff(t *testing.T) { Max: maxT, Factor: factor, } - for i := 0; i < 10; i++ { + for range 10 { require.Equal(t, maxT, b.Duration()) } } @@ -163,13 +163,13 @@ func TestForward(t *testing.T) { Max: maxT, Factor: factor, } - for i := 0; i < n; i++ { + for range n { b.Forward() } require.Equal(t, n, b.cwnd) b.Reset() require.Equal(t, 0, b.cwnd) - for i := 0; i < n; i++ { + for range n { b.BoundaryForward() } require.Equal(t, 3, b.cwnd) diff --git a/dm/pkg/binlog/event/common.go b/dm/pkg/binlog/event/common.go index 5d36153b1f..51c7d8f79d 100644 --- a/dm/pkg/binlog/event/common.go +++ b/dm/pkg/binlog/event/common.go @@ -176,7 +176,7 @@ func GTIDIncrease(flavor string, gSet gmysql.GTIDSet) (gmysql.GTIDSet, error) { } // verifySingleGTID verifies gSet whether only containing a single valid GTID. -func verifySingleGTID(flavor string, gSet gmysql.GTIDSet) (interface{}, error) { +func verifySingleGTID(flavor string, gSet gmysql.GTIDSet) (any, error) { if gtid.CheckGTIDSetEmpty(gSet) { return nil, terror.ErrBinlogEmptyGTID.Generate() } diff --git a/dm/pkg/binlog/event/dml.go b/dm/pkg/binlog/event/dml.go index 881fba6871..9bd7a2f3ad 100644 --- a/dm/pkg/binlog/event/dml.go +++ b/dm/pkg/binlog/event/dml.go @@ -28,7 +28,7 @@ type DMLData struct { Schema string Table string ColumnType []byte - Rows [][]interface{} + Rows [][]any // if Query is not empty, we generate a Query event Query string diff --git a/dm/pkg/binlog/event/dml_test.go b/dm/pkg/binlog/event/dml_test.go index 0a2ee94753..325ba2de64 100644 --- a/dm/pkg/binlog/event/dml_test.go +++ b/dm/pkg/binlog/event/dml_test.go @@ -43,8 +43,8 @@ func TestGenDMLEvent(t *testing.T) { require.Nil(t, result) // single INSERT without batch - insertRows1 := make([][]interface{}, 0, 1) - insertRows1 = append(insertRows1, []interface{}{int32(11), "string column value"}) + insertRows1 := make([][]any, 0, 1) + insertRows1 = append(insertRows1, []any{int32(11), "string column value"}) insertDMLData := []*DMLData{ { TableID: 11, @@ -69,8 +69,8 @@ func TestGenDMLEvent(t *testing.T) { xid++ // multi INSERT with batch - insertRows2 := make([][]interface{}, 0, 2) - insertRows2 = append(insertRows2, []interface{}{int32(101), "string column value a"}, []interface{}{int32(102), "string column value b"}) + insertRows2 := make([][]any, 0, 2) + insertRows2 = append(insertRows2, []any{int32(101), "string column value a"}, []any{int32(102), "string column value b"}) insertDMLData = append(insertDMLData, &DMLData{ TableID: 12, Schema: "db2", @@ -91,8 +91,8 @@ func TestGenDMLEvent(t *testing.T) { xid++ // single UPDATE - updateRows := make([][]interface{}, 0, 2) - updateRows = append(updateRows, []interface{}{int32(21), "old string"}, []interface{}{int32(21), "new string"}) + updateRows := make([][]any, 0, 2) + updateRows = append(updateRows, []any{int32(21), "old string"}, []any{int32(21), "new string"}) updateDMLData := []*DMLData{ { TableID: 21, @@ -121,8 +121,8 @@ func TestGenDMLEvent(t *testing.T) { require.Nil(t, err) // single DELETE - deleteRows := make([][]interface{}, 0, 1) - deleteRows = append(deleteRows, []interface{}{int32(31), "string a"}) + deleteRows := make([][]any, 0, 1) + deleteRows = append(deleteRows, []any{int32(31), "string a"}) deleteDMLData := []*DMLData{ { TableID: 31, diff --git a/dm/pkg/binlog/event/event.go b/dm/pkg/binlog/event/event.go index a0994de10c..dc5dded8d6 100644 --- a/dm/pkg/binlog/event/event.go +++ b/dm/pkg/binlog/event/event.go @@ -521,7 +521,7 @@ func GenTableMapEvent(header *replication.EventHeader, latestPos uint32, tableID // // ref: https://dev.mysql.com/doc/internals/en/rows-event.html // ref: http://blog.51cto.com/yanzongshuai/2090894 -func GenRowsEvent(header *replication.EventHeader, latestPos uint32, eventType replication.EventType, tableID uint64, rowsFlags uint16, rows [][]interface{}, columnType []byte, tableMapEv *replication.BinlogEvent) (*replication.BinlogEvent, error) { +func GenRowsEvent(header *replication.EventHeader, latestPos uint32, eventType replication.EventType, tableID uint64, rowsFlags uint16, rows [][]any, columnType []byte, tableMapEv *replication.BinlogEvent) (*replication.BinlogEvent, error) { switch eventType { case replication.WRITE_ROWS_EVENTv0, replication.WRITE_ROWS_EVENTv1, replication.WRITE_ROWS_EVENTv2, replication.UPDATE_ROWS_EVENTv0, replication.UPDATE_ROWS_EVENTv1, replication.UPDATE_ROWS_EVENTv2, diff --git a/dm/pkg/binlog/event/event_test.go b/dm/pkg/binlog/event/event_test.go index 87dbc83596..0ac182fd46 100644 --- a/dm/pkg/binlog/event/event_test.go +++ b/dm/pkg/binlog/event/event_test.go @@ -480,7 +480,7 @@ func TestGenRowsEvent(t *testing.T) { tableID uint64 = 108 eventType = replication.TABLE_MAP_EVENT rowsFlag = RowFlagsEndOfStatement - rows [][]interface{} + rows [][]any columnType []byte // nil ) @@ -496,7 +496,7 @@ func TestGenRowsEvent(t *testing.T) { require.Nil(t, rowsEv) // valid eventType and rows, invalid columnType - row := []interface{}{int32(1)} + row := []any{int32(1)} rows = append(rows, row) rowsEv, err = GenRowsEvent(header, latestPos, eventType, tableID, rowsFlag, rows, columnType, nil) require.NotNil(t, err) @@ -522,15 +522,15 @@ func TestGenRowsEvent(t *testing.T) { require.Equal(t, rows, rowsEvBody.Rows) // multi rows, with different length, invalid - rows = append(rows, []interface{}{int32(1), int32(2)}) + rows = append(rows, []any{int32(1), int32(2)}) rowsEv, err = GenRowsEvent(header, latestPos, eventType, tableID, rowsFlag, rows, columnType, nil) require.NotNil(t, err) require.Nil(t, rowsEv) // multi rows, multi columns, valid - rows = make([][]interface{}, 0, 2) - rows = append(rows, []interface{}{int32(1), int32(2)}) - rows = append(rows, []interface{}{int32(3), int32(4)}) + rows = make([][]any, 0, 2) + rows = append(rows, []any{int32(1), int32(2)}) + rows = append(rows, []any{int32(3), int32(4)}) columnType = []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_LONG} rowsEv, err = GenRowsEvent(header, latestPos, eventType, tableID, rowsFlag, rows, columnType, nil) require.Nil(t, err) @@ -556,8 +556,8 @@ func TestGenRowsEvent(t *testing.T) { } // more column types - rows = make([][]interface{}, 0, 1) - rows = append(rows, []interface{}{ + rows = make([][]any, 0, 1) + rows = append(rows, []any{ int32(1), int8(2), int16(3), int32(4), int64(5), float32(1.23), float64(4.56), "string with type STRING", }) @@ -582,8 +582,8 @@ func TestGenRowsEvent(t *testing.T) { require.Nil(t, rowsEv) // NotSupported column type - rows = make([][]interface{}, 0, 1) - rows = append(rows, []interface{}{int32(1)}) + rows = make([][]any, 0, 1) + rows = append(rows, []any{int32(1)}) unsupportedTypes := []byte{ gmysql.MYSQL_TYPE_VARCHAR, gmysql.MYSQL_TYPE_VAR_STRING, gmysql.MYSQL_TYPE_NEWDECIMAL, gmysql.MYSQL_TYPE_BIT, diff --git a/dm/pkg/binlog/event/generator_test.go b/dm/pkg/binlog/event/generator_test.go index 5bee26a4f3..2c163d7a2d 100644 --- a/dm/pkg/binlog/event/generator_test.go +++ b/dm/pkg/binlog/event/generator_test.go @@ -165,8 +165,8 @@ func testGenerate(t *testing.T, flavor string, serverID uint32, latestGTID gmysq tableID uint64 = 8 columnType = []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_STRING} ) - insertRows := make([][]interface{}, 0, 1) - insertRows = append(insertRows, []interface{}{int32(1), "string 1"}) + insertRows := make([][]any, 0, 1) + insertRows = append(insertRows, []any{int32(1), "string 1"}) dmlData := []*DMLData{ { TableID: tableID, @@ -186,10 +186,10 @@ func testGenerate(t *testing.T, flavor string, serverID uint32, latestGTID gmysq // INSERT INTO `db`.`tbl` VALUES (11, "string 11"), (12, "string 12") // INSERT INTO `db`.`tbl` VALUES (13, "string 13"), - insertRows1 := make([][]interface{}, 0, 2) - insertRows1 = append(insertRows1, []interface{}{int32(11), "string 11"}, []interface{}{int32(12), "string 12"}) - insertRows2 := make([][]interface{}, 0, 1) - insertRows2 = append(insertRows2, []interface{}{int32(13), "string 13"}) + insertRows1 := make([][]any, 0, 2) + insertRows1 = append(insertRows1, []any{int32(11), "string 11"}, []any{int32(12), "string 12"}) + insertRows2 := make([][]any, 0, 1) + insertRows2 = append(insertRows2, []any{int32(13), "string 13"}) dmlData = []*DMLData{ { TableID: tableID, @@ -215,10 +215,10 @@ func testGenerate(t *testing.T, flavor string, serverID uint32, latestGTID gmysq // UPDATE `db`.`tbl` SET c2="another string 11" WHERE c1=11 // UPDATE `db`.`tbl` SET c1=120, c2="another string 120" WHERE C1=12 - updateRows1 := make([][]interface{}, 0, 2) - updateRows1 = append(updateRows1, []interface{}{int32(11), "string 11"}, []interface{}{int32(11), "another string 11"}) - updateRows2 := make([][]interface{}, 0, 2) - updateRows2 = append(updateRows2, []interface{}{int32(12), "string 12"}, []interface{}{int32(120), "another string 120"}) + updateRows1 := make([][]any, 0, 2) + updateRows1 = append(updateRows1, []any{int32(11), "string 11"}, []any{int32(11), "another string 11"}) + updateRows2 := make([][]any, 0, 2) + updateRows2 = append(updateRows2, []any{int32(12), "string 12"}, []any{int32(120), "another string 120"}) dmlData = []*DMLData{ { TableID: tableID, @@ -244,8 +244,8 @@ func testGenerate(t *testing.T, flavor string, serverID uint32, latestGTID gmysq allEventTypes = append(allEventTypes, gtidEventType(t, flavor), replication.QUERY_EVENT, replication.TABLE_MAP_EVENT, eventType, replication.TABLE_MAP_EVENT, eventType, replication.XID_EVENT) // DELETE FROM `db`.`tbl` WHERE c1=13 - deleteRows := make([][]interface{}, 0, 1) - deleteRows = append(deleteRows, []interface{}{int32(13), "string 13"}) + deleteRows := make([][]any, 0, 1) + deleteRows = append(deleteRows, []any{int32(13), "string 13"}) dmlData = []*DMLData{ { TableID: tableID, diff --git a/dm/pkg/binlog/event/util.go b/dm/pkg/binlog/event/util.go index 4465fa41a3..077ee563dd 100644 --- a/dm/pkg/binlog/event/util.go +++ b/dm/pkg/binlog/event/util.go @@ -111,7 +111,7 @@ func nullBytes(n int) []byte { // fullBytes returns a n-length full bytes slice (all bits are set). func fullBytes(n int) []byte { buf := new(bytes.Buffer) - for i := 0; i < n; i++ { + for range n { buf.WriteByte(0xff) } return buf.Bytes() @@ -197,7 +197,7 @@ func combineHeaderPayload(buf *bytes.Buffer, header, postHeader, payload []byte) // ref: https://github.com/go-mysql-org/go-mysql/blob/88e9cd7f6643b246b4dcc0e3206e9a169dd0ac96/replication/row_event.go#L368 // NOTE: we do not generate meaningful `meta` yet. // nolint:unparam -func encodeColumnValue(v interface{}, tp byte, meta uint16) ([]byte, error) { +func encodeColumnValue(v any, tp byte, meta uint16) ([]byte, error) { var ( buf = new(bytes.Buffer) err error @@ -206,33 +206,33 @@ func encodeColumnValue(v interface{}, tp byte, meta uint16) ([]byte, error) { case gmysql.MYSQL_TYPE_NULL: return nil, nil case gmysql.MYSQL_TYPE_LONG: - err = writeIntegerColumnValue(buf, v, reflect.TypeOf(int32(0))) + err = writeIntegerColumnValue(buf, v, reflect.TypeFor[int32]()) case gmysql.MYSQL_TYPE_TINY: - err = writeIntegerColumnValue(buf, v, reflect.TypeOf(int8(0))) + err = writeIntegerColumnValue(buf, v, reflect.TypeFor[int8]()) case gmysql.MYSQL_TYPE_SHORT: - err = writeIntegerColumnValue(buf, v, reflect.TypeOf(int16(0))) + err = writeIntegerColumnValue(buf, v, reflect.TypeFor[int16]()) case gmysql.MYSQL_TYPE_INT24: - err = writeIntegerColumnValue(buf, v, reflect.TypeOf(int32(0))) + err = writeIntegerColumnValue(buf, v, reflect.TypeFor[int32]()) if err == nil { buf.Truncate(3) } case gmysql.MYSQL_TYPE_LONGLONG: - err = writeIntegerColumnValue(buf, v, reflect.TypeOf(int64(0))) + err = writeIntegerColumnValue(buf, v, reflect.TypeFor[int64]()) case gmysql.MYSQL_TYPE_FLOAT: value, ok := v.(float32) if !ok { - err = terror.ErrBinlogColumnTypeMisMatch.Generate(v, reflect.TypeOf(v), reflect.TypeOf(float32(0))) + err = terror.ErrBinlogColumnTypeMisMatch.Generate(v, reflect.TypeOf(v), reflect.TypeFor[float32]()) } else { bits := math.Float32bits(value) - err = writeIntegerColumnValue(buf, bits, reflect.TypeOf(uint32(0))) + err = writeIntegerColumnValue(buf, bits, reflect.TypeFor[uint32]()) } case gmysql.MYSQL_TYPE_DOUBLE: value, ok := v.(float64) if !ok { - err = terror.ErrBinlogColumnTypeMisMatch.Generate(v, reflect.TypeOf(v), reflect.TypeOf(float64(0))) + err = terror.ErrBinlogColumnTypeMisMatch.Generate(v, reflect.TypeOf(v), reflect.TypeFor[float64]()) } else { bits := math.Float64bits(value) - err = writeIntegerColumnValue(buf, bits, reflect.TypeOf(uint64(0))) + err = writeIntegerColumnValue(buf, bits, reflect.TypeFor[uint64]()) } case gmysql.MYSQL_TYPE_STRING: err = writeStringColumnValue(buf, v) @@ -252,7 +252,7 @@ func encodeColumnValue(v interface{}, tp byte, meta uint16) ([]byte, error) { } // writeIntegerColumnValue writes integer value to bytes buffer. -func writeIntegerColumnValue(buf *bytes.Buffer, value interface{}, valueType reflect.Type) error { +func writeIntegerColumnValue(buf *bytes.Buffer, value any, valueType reflect.Type) error { if reflect.TypeOf(value) != valueType { return terror.ErrBinlogColumnTypeMisMatch.Generate(value, reflect.TypeOf(value), valueType) } @@ -260,10 +260,10 @@ func writeIntegerColumnValue(buf *bytes.Buffer, value interface{}, valueType ref } // writeStringColumnValue writes string value to bytes buffer. -func writeStringColumnValue(buf *bytes.Buffer, value interface{}) error { +func writeStringColumnValue(buf *bytes.Buffer, value any) error { str, ok := value.(string) if !ok { - return terror.ErrBinlogColumnTypeMisMatch.Generate(value, reflect.TypeOf(value), reflect.TypeOf("")) + return terror.ErrBinlogColumnTypeMisMatch.Generate(value, reflect.TypeOf(value), reflect.TypeFor[string]()) } var ( err error diff --git a/dm/pkg/binlog/pos_finder_test.go b/dm/pkg/binlog/pos_finder_test.go index 7fb72963f0..443db6f38a 100644 --- a/dm/pkg/binlog/pos_finder_test.go +++ b/dm/pkg/binlog/pos_finder_test.go @@ -38,7 +38,7 @@ func genBinlogFile(generator *event.Generator, start time.Time, nextFile string) Schema: fmt.Sprintf("db_%d", 1), Table: strconv.Itoa(1), ColumnType: []byte{mysql.MYSQL_TYPE_INT24}, - Rows: [][]interface{}{{int32(1)}, {int32(2)}}, + Rows: [][]any{{int32(1)}, {int32(2)}}, }, } allEvents := make([]*replication.BinlogEvent, 0) @@ -79,7 +79,7 @@ func TestTransBoundary(t *testing.T) { Schema: fmt.Sprintf("db_%d", 1), Table: strconv.Itoa(1), ColumnType: []byte{mysql.MYSQL_TYPE_INT24}, - Rows: [][]interface{}{{int32(1)}, {int32(2)}}, + Rows: [][]any{{int32(1)}, {int32(2)}}, }, } var buf bytes.Buffer @@ -102,7 +102,7 @@ func TestTransBoundary(t *testing.T) { header.Timestamp = uint32(ts) mapEvent, _ := event.GenTableMapEvent(header, beginEvent.Header.LogPos, 1, []byte("test"), []byte("t"), []byte{mysql.MYSQL_TYPE_INT24}) buf.Write(mapEvent.RawData) - rowsEvent, _ := event.GenRowsEvent(header, mapEvent.Header.LogPos, replication.WRITE_ROWS_EVENTv2, 1, 1, [][]interface{}{{int32(1)}, {int32(2)}}, []byte{mysql.MYSQL_TYPE_INT24}, mapEvent) + rowsEvent, _ := event.GenRowsEvent(header, mapEvent.Header.LogPos, replication.WRITE_ROWS_EVENTv2, 1, 1, [][]any{{int32(1)}, {int32(2)}}, []byte{mysql.MYSQL_TYPE_INT24}, mapEvent) buf.Write(rowsEvent.RawData) xidEvent, _ := event.GenXIDEvent(header, rowsEvent.Header.LogPos, 1) buf.Write(xidEvent.RawData) diff --git a/dm/pkg/binlog/reader/file.go b/dm/pkg/binlog/reader/file.go index fd2d507e09..1289a45f5f 100644 --- a/dm/pkg/binlog/reader/file.go +++ b/dm/pkg/binlog/reader/file.go @@ -106,9 +106,7 @@ func (r *FileReader) StartSyncByPos(pos gmysql.Position) error { // keep running until canceled in `Close`. r.ctx, r.cancel = context.WithCancel(context.Background()) - r.wg.Add(1) - go func() { - defer r.wg.Done() + r.wg.Go(func() { err := r.parser.ParseFile(pos.Name, int64(pos.Pos), r.onEvent) if err != nil { if errors.Cause(err) != context.Canceled { @@ -122,7 +120,7 @@ func (r *FileReader) StartSyncByPos(pos gmysql.Position) error { r.logger.Info("parse end of binlog file", zap.Uint32("pos", r.readOffset.Load())) close(r.endCh) } - }() + }) r.stage = common.StagePrepared return nil @@ -173,7 +171,7 @@ func (r *FileReader) GetEvent(ctx context.Context) (*replication.BinlogEvent, er } // Status implements Reader.Status. -func (r *FileReader) Status() interface{} { +func (r *FileReader) Status() any { r.mu.RLock() stage := r.stage r.mu.RUnlock() diff --git a/dm/pkg/binlog/reader/file_test.go b/dm/pkg/binlog/reader/file_test.go index 1d9fc2eb27..03380070d2 100644 --- a/dm/pkg/binlog/reader/file_test.go +++ b/dm/pkg/binlog/reader/file_test.go @@ -171,10 +171,10 @@ func TestGetEvent(t *testing.T) { // write two QueryEvent var queryEv *replication.BinlogEvent - for i := 0; i < 2; i++ { + for i := range 2 { queryEv, err = event.GenQueryEvent( header, latestPos, 0, 0, 0, nil, - []byte(fmt.Sprintf("schema-%d", i)), []byte(fmt.Sprintf("query-%d", i))) + fmt.Appendf(nil, "schema-%d", i), fmt.Appendf(nil, "query-%d", i)) require.Nil(t, err) require.NotNil(t, queryEv) _, err = f.Write(queryEv.RawData) @@ -245,7 +245,7 @@ func TestWithChannelBuffer(t *testing.T) { for i := 0; i < cfg.ChBufferSize; i++ { queryEv, err = event.GenQueryEvent( header, latestPos, 0, 0, 0, nil, - []byte(fmt.Sprintf("schema-%d", i)), []byte(fmt.Sprintf("query-%d", i))) + fmt.Appendf(nil, "schema-%d", i), fmt.Appendf(nil, "query-%d", i)) require.Nil(t, err) require.NotNil(t, queryEv) _, err = f.Write(queryEv.RawData) diff --git a/dm/pkg/binlog/reader/mock.go b/dm/pkg/binlog/reader/mock.go index 70af1774a4..06d46050cc 100644 --- a/dm/pkg/binlog/reader/mock.go +++ b/dm/pkg/binlog/reader/mock.go @@ -67,7 +67,7 @@ func (r *MockReader) GetEvent(ctx context.Context) (*replication.BinlogEvent, er } // Status implements Reader.Status. -func (r *MockReader) Status() interface{} { +func (r *MockReader) Status() any { return nil } diff --git a/dm/pkg/binlog/reader/reader.go b/dm/pkg/binlog/reader/reader.go index 7e04b3011e..e3b99b8476 100644 --- a/dm/pkg/binlog/reader/reader.go +++ b/dm/pkg/binlog/reader/reader.go @@ -36,7 +36,7 @@ type Reader interface { Close() error // Status returns the status of the reader. - Status() interface{} + Status() any } // Streamer provides the ability to get binlog event from remote server or local file. diff --git a/dm/pkg/binlog/reader/tcp.go b/dm/pkg/binlog/reader/tcp.go index 5d2053136f..9618aeef87 100644 --- a/dm/pkg/binlog/reader/tcp.go +++ b/dm/pkg/binlog/reader/tcp.go @@ -151,7 +151,7 @@ func (r *TCPReader) GetEvent(ctx context.Context) (*replication.BinlogEvent, err } // Status implements Reader.Status. -func (r *TCPReader) Status() interface{} { +func (r *TCPReader) Status() any { r.mu.RLock() stage := r.stage r.mu.RUnlock() diff --git a/dm/pkg/checker/primary_key.go b/dm/pkg/checker/primary_key.go index 15b5167840..6020eaaf48 100644 --- a/dm/pkg/checker/primary_key.go +++ b/dm/pkg/checker/primary_key.go @@ -150,7 +150,7 @@ func (c *PrimaryKeyChecker) Check(ctx context.Context) *Result { } }) - for i := 0; i < concurrency; i++ { + for range concurrency { worker := &primaryKeyWorker{c: c} pool.Go(worker.handle) } diff --git a/dm/pkg/checker/real_checker.go b/dm/pkg/checker/real_checker.go index e86bee6180..6ee3591c6f 100644 --- a/dm/pkg/checker/real_checker.go +++ b/dm/pkg/checker/real_checker.go @@ -47,12 +47,12 @@ type Error struct { } // NewError creates a pointer to Error, the parameters could be used as in Sprintf. -func NewError(description string, args ...interface{}) *Error { +func NewError(description string, args ...any) *Error { return &Error{Severity: StateFailure, ShortErr: fmt.Sprintf(description, args...)} } // NewWarn creates a pointer to Error, the parameters could be used as in Sprintf. -func NewWarn(description string, args ...interface{}) *Error { +func NewWarn(description string, args ...any) *Error { return &Error{Severity: StateWarning, ShortErr: fmt.Sprintf(description, args...)} } @@ -104,9 +104,7 @@ func Do(ctx context.Context, checkers []RealChecker) (*Results, error) { resultCh := make(chan *Result) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { result := <-resultCh switch result.State { @@ -126,7 +124,7 @@ func Do(ctx context.Context, checkers []RealChecker) (*Results, error) { return } } - }() + }) for i, checker := range checkers { wg.Add(1) diff --git a/dm/pkg/checker/table_structure.go b/dm/pkg/checker/table_structure.go index b2ccc24dda..8e17d7c909 100644 --- a/dm/pkg/checker/table_structure.go +++ b/dm/pkg/checker/table_structure.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "math" + "slices" "strings" "sync" "time" @@ -222,7 +223,7 @@ func (c *TablesChecker) Check(ctx context.Context) *Result { ctx, everyOptHandler, ) - for i := 0; i < concurrency; i++ { + for range concurrency { worker := &tablesCheckerWorker{c: c} worker.downstreamParser, err = dbutil.GetParserForDB(ctx, c.downstreamDB.DB) if err != nil { @@ -312,13 +313,7 @@ func (c *TablesChecker) checkAST( } } // check primary/unique key - hasUnique := false - for _, cst := range upstreamStmt.Constraints { - if c.checkUnique(cst) { - hasUnique = true - break - } - } + hasUnique := slices.ContainsFunc(upstreamStmt.Constraints, c.checkUnique) if !hasUnique { options = append(options, &incompatibilityOption{ state: StateWarning, @@ -585,7 +580,7 @@ func (c *ShardingTablesChecker) Check(ctx context.Context) *Result { return r } eg, checkCtx := errgroup.WithContext(ctx) - for i := 0; i < concurrency; i++ { + for range concurrency { eg.Go(func() error { return c.checkShardingTable(checkCtx, r) }) @@ -824,7 +819,7 @@ func (c *OptimisticShardingTablesChecker) Check(ctx context.Context) *Result { return r } eg, checkCtx := errgroup.WithContext(ctx) - for i := 0; i < concurrency; i++ { + for range concurrency { eg.Go(func() error { return c.checkTable(checkCtx, r) }) diff --git a/dm/pkg/checker/worker_pool_test.go b/dm/pkg/checker/worker_pool_test.go index 4588ef556f..68d4dcd10f 100644 --- a/dm/pkg/checker/worker_pool_test.go +++ b/dm/pkg/checker/worker_pool_test.go @@ -55,11 +55,11 @@ func TestExampleWorkerPool(t *testing.T) { pool := NewWorkerPool[job, int64](func(result int64) { sum += result }) - for i := 0; i < concurrency; i++ { + for range concurrency { worker := &baseAdder{base: 666} pool.Go(worker.add) } - for i := 0; i < jobNum; i++ { + for range jobNum { pool.PutJob(job{inc: &incrementer}) } @@ -95,11 +95,11 @@ func TestExampleWorkerPoolError(t *testing.T) { pool := NewWorkerPool[job, int64](func(result int64) { sum += result }) - for i := 0; i < concurrency; i++ { + for range concurrency { worker := &baseAdder{base: 666} pool.Go(worker.addAndError) } - for i := 0; i < jobNum; i++ { + for i := range jobNum { ok := pool.PutJob(job{inc: &incrementer}) if !ok { require.GreaterOrEqual(t, int64(i), errorAt) diff --git a/dm/pkg/conn/baseconn.go b/dm/pkg/conn/baseconn.go index a14c78c3de..68352dc94a 100644 --- a/dm/pkg/conn/baseconn.go +++ b/dm/pkg/conn/baseconn.go @@ -111,7 +111,7 @@ func (conn *BaseConn) SetRetryStrategy(strategy retry.Strategy) error { } // QuerySQL runs a query statement. -func (conn *BaseConn) QuerySQL(tctx *tcontext.Context, query string, args ...interface{}) (*sql.Rows, error) { +func (conn *BaseConn) QuerySQL(tctx *tcontext.Context, query string, args ...any) (*sql.Rows, error) { if conn == nil || conn.DBConn == nil { return nil, terror.ErrDBUnExpect.Generate("database connection not valid") } @@ -134,7 +134,7 @@ func (conn *BaseConn) QuerySQL(tctx *tcontext.Context, query string, args ...int // return // 1. failed: (the index of sqls executed error, error) // 2. succeed: (rows affected, nil). -func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *prometheus.HistogramVec, task string, ignoreErr func(error) bool, queries []string, args ...[]interface{}) (int, error) { +func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *prometheus.HistogramVec, task string, ignoreErr func(error) bool, queries []string, args ...[]any) (int, error) { var affect int64 // inject an error to trigger retry, this should be placed before the real execution of the SQL statement. failpoint.Inject("retryableError", func(val failpoint.Value) { @@ -174,7 +174,7 @@ func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *pr l := len(queries) for i, query := range queries { - var arg []interface{} + var arg []any if len(args) > i { arg = args[i] } @@ -236,7 +236,7 @@ func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *pr // return // 1. failed: (the index of sqls executed error, error) // 2. succeed: (rows affected, nil). -func (conn *BaseConn) ExecuteSQL(tctx *tcontext.Context, hVec *prometheus.HistogramVec, task string, queries []string, args ...[]interface{}) (int, error) { +func (conn *BaseConn) ExecuteSQL(tctx *tcontext.Context, hVec *prometheus.HistogramVec, task string, queries []string, args ...[]any) (int, error) { return conn.ExecuteSQLWithIgnoreError(tctx, hVec, task, nil, queries, args...) } @@ -248,7 +248,7 @@ func (conn *BaseConn) ExecuteSQLsAutoSplit( hVec *prometheus.HistogramVec, task string, queries []string, - args ...[]interface{}, + args ...[]any, ) error { _, err := conn.ExecuteSQL(tctx, hVec, task, queries, args...) mysqlErr, ok := errors.Cause(err).(*mysql.MySQLError) @@ -270,8 +270,8 @@ func (conn *BaseConn) ExecuteSQLsAutoSplit( // ApplyRetryStrategy apply specify strategy for BaseConn. func (conn *BaseConn) ApplyRetryStrategy(tctx *tcontext.Context, params retry.Params, - operateFn func(*tcontext.Context) (interface{}, error), -) (interface{}, int, error) { + operateFn func(*tcontext.Context) (any, error), +) (any, int, error) { return conn.RetryStrategy.Apply(tctx, params, operateFn) } @@ -290,7 +290,7 @@ func (conn *BaseConn) forceClose() error { return nil } - err := conn.DBConn.Raw(func(dc interface{}) error { + err := conn.DBConn.Raw(func(dc any) error { // return an `ErrBadConn` to ensure close the connection, but do not put it back to the pool. // if we choose to use `Close`, it will always put the connection back to the pool. return driver.ErrBadConn diff --git a/dm/pkg/conn/baseconn_test.go b/dm/pkg/conn/baseconn_test.go index 8be2cf5c38..4e67eb50fd 100644 --- a/dm/pkg/conn/baseconn_test.go +++ b/dm/pkg/conn/baseconn_test.go @@ -121,7 +121,7 @@ func TestAutoSplit4TxnTooLarge(t *testing.T) { mockTxn := func(size int) { mock.ExpectBegin() - for i := 0; i < size; i++ { + for range size { mock.ExpectExec(dml).WillReturnResult(sqlmock.NewResult(1, 1)) } if size == 1 { @@ -138,14 +138,14 @@ func TestAutoSplit4TxnTooLarge(t *testing.T) { mockTxn(1) // [2] mockTxn(1) // [3] txn := []string{dml, dml, dml} - args := [][]interface{}{nil, nil, nil} + args := [][]any{nil, nil, nil} err = baseConn.ExecuteSQLsAutoSplit(tctx, nil, "test", txn, args...) require.NoError(t, err) mockTxnAlwaysError := func(size int) { mock.ExpectBegin() - for i := 0; i < size; i++ { + for range size { mock.ExpectExec(dml).WillReturnResult(sqlmock.NewResult(1, 1)) } mock.ExpectCommit().WillReturnError(errTxnTooLarge) diff --git a/dm/pkg/conn/basedb.go b/dm/pkg/conn/basedb.go index f4ef42ebda..f5c47d1ea8 100644 --- a/dm/pkg/conn/basedb.go +++ b/dm/pkg/conn/basedb.go @@ -115,8 +115,9 @@ func (d *DefaultDBProviderImpl) ApplyWithPingTimeout(config ScopedDBConfig, ping if config.Net != "" { net = config.Net } - dsn := fmt.Sprintf("%s:%s@%s(%s)/?charset=utf8mb4&interpolateParams=true&maxAllowedPacket=0", - config.User, config.Password, net, hostPort) + var dsn strings.Builder + dsn.WriteString(fmt.Sprintf("%s:%s@%s(%s)/?charset=utf8mb4&interpolateParams=true&maxAllowedPacket=0", + config.User, config.Password, net, hostPort)) doFuncInClose := func() {} if config.Security != nil { @@ -139,7 +140,7 @@ func (d *DefaultDBProviderImpl) ApplyWithPingTimeout(config ScopedDBConfig, ping if err != nil { return nil, terror.ErrConnRegistryTLSConfig.Delegate(err) } - dsn += "&tls=" + name + dsn.WriteString("&tls=" + name) doFuncInClose = func() { mysql.DeregisterTLSConfig(name) @@ -151,10 +152,10 @@ func (d *DefaultDBProviderImpl) ApplyWithPingTimeout(config ScopedDBConfig, ping rawCfg := config.RawDBCfg if rawCfg != nil { if rawCfg.ReadTimeout != "" { - dsn += fmt.Sprintf("&readTimeout=%s", rawCfg.ReadTimeout) + dsn.WriteString(fmt.Sprintf("&readTimeout=%s", rawCfg.ReadTimeout)) } if rawCfg.WriteTimeout != "" { - dsn += fmt.Sprintf("&writeTimeout=%s", rawCfg.WriteTimeout) + dsn.WriteString(fmt.Sprintf("&writeTimeout=%s", rawCfg.WriteTimeout)) } maxIdleConns = rawCfg.MaxIdleConns } @@ -167,14 +168,14 @@ func (d *DefaultDBProviderImpl) ApplyWithPingTimeout(config ScopedDBConfig, ping if strings.ToLower(key) == "foreign_key_checks" { setFK = true } - dsn += fmt.Sprintf("&%s='%s'", key, url.QueryEscape(val)) + dsn.WriteString(fmt.Sprintf("&%s='%s'", key, url.QueryEscape(val))) } if !setFK { - dsn += "&foreign_key_checks=0" + dsn.WriteString("&foreign_key_checks=0") } - db, err := sql.Open("mysql", dsn) + db, err := sql.Open("mysql", dsn.String()) if err != nil { return nil, terror.DBErrorAdapt(err, config.Scope, terror.ErrDBDriverError) } @@ -290,7 +291,7 @@ func (d *BaseDB) GetBaseConn(ctx context.Context) (*BaseConn, error) { } // TODO: retry can be done inside the BaseDB. -func (d *BaseDB) ExecContext(tctx *tcontext.Context, query string, args ...interface{}) (sql.Result, error) { +func (d *BaseDB) ExecContext(tctx *tcontext.Context, query string, args ...any) (sql.Result, error) { if tctx.L().Core().Enabled(zap.DebugLevel) { tctx.L().Debug("exec context", zap.String("query", utils.TruncateString(query, -1)), @@ -300,7 +301,7 @@ func (d *BaseDB) ExecContext(tctx *tcontext.Context, query string, args ...inter } // TODO: retry can be done inside the BaseDB. -func (d *BaseDB) QueryContext(tctx *tcontext.Context, query string, args ...interface{}) (*sql.Rows, error) { +func (d *BaseDB) QueryContext(tctx *tcontext.Context, query string, args ...any) (*sql.Rows, error) { if tctx.L().Core().Enabled(zap.DebugLevel) { tctx.L().Debug("query context", zap.String("query", utils.TruncateString(query, -1)), @@ -309,8 +310,8 @@ func (d *BaseDB) QueryContext(tctx *tcontext.Context, query string, args ...inte return d.DB.QueryContext(tctx.Ctx, query, args...) } -func (d *BaseDB) DoTxWithRetry(tctx *tcontext.Context, queries []string, args [][]interface{}, retryer retry.Retryer) error { - workFunc := func(tctx *tcontext.Context) (interface{}, error) { +func (d *BaseDB) DoTxWithRetry(tctx *tcontext.Context, queries []string, args [][]any, retryer retry.Retryer) error { + workFunc := func(tctx *tcontext.Context) (any, error) { var ( err error tx *sql.Tx diff --git a/dm/pkg/conn/db.go b/dm/pkg/conn/db.go index 762f986e50..6922719cab 100644 --- a/dm/pkg/conn/db.go +++ b/dm/pkg/conn/db.go @@ -88,7 +88,7 @@ func GetRandomServerID(ctx *tcontext.Context, db *BaseDB) (uint32, error) { return 0, err } - for i := 0; i < 99999; i++ { + for range 99999 { randomValue := uint32(rand.Intn(100000)) randomServerID := uint32(defaultBaseServerID) + randomValue if _, ok := serverIDs[randomServerID]; ok { diff --git a/dm/pkg/conn/mockdb.go b/dm/pkg/conn/mockdb.go index 1288e8e1c7..0f322eeed0 100644 --- a/dm/pkg/conn/mockdb.go +++ b/dm/pkg/conn/mockdb.go @@ -212,7 +212,7 @@ func (mock *Cluster) Stop() { func waitUntilServerOnline(statusPort uint) { // connect http status statusURL := fmt.Sprintf("http://127.0.0.1:%d/status", statusPort) - for retry := 0; retry < 100; retry++ { + for range 100 { // nolint:gosec,noctx // #nosec G107 resp, err := http.Get(statusURL) diff --git a/dm/pkg/election/election.go b/dm/pkg/election/election.go index c8b3b7607b..641b4de334 100644 --- a/dm/pkg/election/election.go +++ b/dm/pkg/election/election.go @@ -136,11 +136,9 @@ func NewElection(ctx context.Context, cli *clientv3.Client, sessionTTL int, key, return nil, terror.ErrElectionCampaignFail.Delegate(err, "create the initial session") } - e.bgWg.Add(1) - go func() { - defer e.bgWg.Done() + e.bgWg.Go(func() { e.campaignLoop(ctx2, session) - }() + }) return e, nil } @@ -468,7 +466,7 @@ func (e *Election) newSession(ctx context.Context, retryCnt int) (*concurrency.S ) forLoop: - for i := 0; i < retryCnt; i++ { + for i := range retryCnt { if i > 0 { select { case e.ech <- terror.ErrElectionCampaignFail.Delegate(err, "create a new session"): diff --git a/dm/pkg/election/election_test.go b/dm/pkg/election/election_test.go index 8934a558d8..d7b883c8c1 100644 --- a/dm/pkg/election/election_test.go +++ b/dm/pkg/election/election_test.go @@ -189,9 +189,7 @@ func testElection2After1(t *testElectionSuite, c *check.C, normalExit bool) { c.Assert(resp.Kvs, check.HasLen, 1) // if closing the client when campaigning, we should get an error - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case err2 := <-e2.ErrorNotify(): c.Assert(terror.ErrElectionCampaignFail.Equal(err2), check.IsTrue) @@ -200,7 +198,7 @@ func testElection2After1(t *testElectionSuite, c *check.C, normalExit bool) { case <-time.After(timeout): c.Fatal("do not receive error for e2") } - }() + }) cli.Close() // close the client wg.Wait() @@ -267,15 +265,13 @@ func (t *testElectionSuite) TestElectionAlways1(c *check.C) { // cancel the campaign for e2, should get no errors var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case err2 := <-e2.ErrorNotify(): c.Fatalf("cancel the campaign should not get an error, %v", err2) case <-time.After(timeout): // wait 3s } - }() + }) cancel2() wg.Wait() diff --git a/dm/pkg/etcdutil/etcdutil.go b/dm/pkg/etcdutil/etcdutil.go index d0ba3df8fa..e635de77fd 100644 --- a/dm/pkg/etcdutil/etcdutil.go +++ b/dm/pkg/etcdutil/etcdutil.go @@ -88,7 +88,7 @@ func RemoveMember(client *clientv3.Client, id uint64) (*clientv3.MemberRemoveRes return client.MemberRemove(ctx, id) } -type EtcdOpFunc func(*tcontext.Context, *clientv3.Client) (interface{}, error) +type EtcdOpFunc func(*tcontext.Context, *clientv3.Client) (any, error) // DoTxnWithRepeatable do multiple etcd operations in one txn with repeatable retry. // There are two situations that this function can be used: @@ -100,7 +100,7 @@ func DoTxnWithRepeatable(cli *clientv3.Client, opFunc EtcdOpFunc) (*clientv3.Txn defer cancel() tctx := tcontext.NewContext(ctx, log.L()) - ret, _, err := etcdDefaultTxnStrategy.Apply(tctx, etcdDefaultTxnRetryParam, func(t *tcontext.Context) (interface{}, error) { + ret, _, err := etcdDefaultTxnStrategy.Apply(tctx, etcdDefaultTxnRetryParam, func(t *tcontext.Context) (any, error) { return opFunc(t, cli) }) if err != nil { @@ -113,7 +113,7 @@ func DoTxnWithRepeatable(cli *clientv3.Client, opFunc EtcdOpFunc) (*clientv3.Txn } func ThenOpFunc(ops ...clientv3.Op) EtcdOpFunc { - return func(tctx *tcontext.Context, cli *clientv3.Client) (interface{}, error) { + return func(tctx *tcontext.Context, cli *clientv3.Client) (any, error) { resp, err := cli.Txn(tctx.Ctx).Then(ops...).Commit() if err != nil { return nil, terror.ErrHAFailTxnOperation.Delegate(err, "txn commit failed") @@ -123,7 +123,7 @@ func ThenOpFunc(ops ...clientv3.Op) EtcdOpFunc { } func FullOpFunc(cmps []clientv3.Cmp, opsThen, opsElse []clientv3.Op) EtcdOpFunc { - return func(tctx *tcontext.Context, cli *clientv3.Client) (interface{}, error) { + return func(tctx *tcontext.Context, cli *clientv3.Client) (any, error) { failpoint.Inject("ErrNoSpace", func() { tctx.L().Info("fail to do ops in etcd", zap.String("failpoint", "ErrNoSpace")) failpoint.Return(nil, v3rpc.ErrNoSpace) diff --git a/dm/pkg/etcdutil/etcdutil_test.go b/dm/pkg/etcdutil/etcdutil_test.go index de37a5b8ec..8b386cdf18 100644 --- a/dm/pkg/etcdutil/etcdutil_test.go +++ b/dm/pkg/etcdutil/etcdutil_test.go @@ -65,7 +65,7 @@ func (t *testEtcdUtilSuite) newConfig(c *check.C, name string, portCount int) *e c.Assert(cfg.Validate(), check.IsNil) cfg.ListenClientUrls = []url.URL{} - for i := 0; i < portCount; i++ { + for range portCount { endPoint := tempurl.Alloc() cu, err2 := url.Parse(endPoint) c.Assert(err2, check.IsNil) @@ -75,7 +75,7 @@ func (t *testEtcdUtilSuite) newConfig(c *check.C, name string, portCount int) *e cfg.AdvertiseClientUrls = cfg.ListenClientUrls cfg.ListenPeerUrls = []url.URL{} ic := make([]string, 0, portCount) - for i := 0; i < portCount; i++ { + for range portCount { endPoint := tempurl.Alloc() pu, err2 := url.Parse(endPoint) c.Assert(err2, check.IsNil) diff --git a/dm/pkg/func-rollback/rollback_test.go b/dm/pkg/func-rollback/rollback_test.go index 6b0bb122e7..84f3b02f8a 100644 --- a/dm/pkg/func-rollback/rollback_test.go +++ b/dm/pkg/func-rollback/rollback_test.go @@ -37,7 +37,7 @@ func TestRollback(t *testing.T) { expected = append(expected, i) // [4, 3, 2, 1, 0] } - for i := 0; i < total; i++ { + for i := range total { h.Add(FuncRollback{Name: fmt.Sprintf("test-%d", i), Fn: rf}) } h.RollbackReverseOrder() diff --git a/dm/pkg/helper/value.go b/dm/pkg/helper/value.go index 5789e5a1c5..c2e41daecc 100644 --- a/dm/pkg/helper/value.go +++ b/dm/pkg/helper/value.go @@ -17,12 +17,12 @@ import "reflect" // IsNil tests whether the passed in value is nil. // ref https://github.com/golang/go/blob/87113f7eadf6d8b12279709f05c0359b54b194ea/src/reflect/value.go#L1049. -func IsNil(vi interface{}) (result bool) { +func IsNil(vi any) (result bool) { if vi == nil { result = true } else { switch v := reflect.ValueOf(vi); v.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Slice: + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.UnsafePointer, reflect.Slice: return v.IsNil() } } diff --git a/dm/pkg/log/ctx_test.go b/dm/pkg/log/ctx_test.go index bf30ce7b2a..df35d041a4 100644 --- a/dm/pkg/log/ctx_test.go +++ b/dm/pkg/log/ctx_test.go @@ -51,7 +51,7 @@ func TestLogCtxTooManyFields(t *testing.T) { fields = append(fields, append(fields[i-1], zap.String(k, v))) } - for i := 0; i < 100; i++ { + for i := range 100 { require.Equal(t, fields[i], getZapFieldsFromCtx(ctxs[i]), "failed, index = %d", i) } } diff --git a/dm/pkg/retry/strategy.go b/dm/pkg/retry/strategy.go index 8700c8b768..ea1f7a6716 100644 --- a/dm/pkg/retry/strategy.go +++ b/dm/pkg/retry/strategy.go @@ -61,7 +61,7 @@ func NewParams(retryCount int, firstRetryDuration time.Duration, backoffStrategy // OperateFunc the function we can retry // // return: (result of operation, error of operation) -type OperateFunc func(*tcontext.Context) (interface{}, error) +type OperateFunc func(*tcontext.Context) (any, error) // Strategy define different kind of retry strategy. type Strategy interface { @@ -71,7 +71,7 @@ type Strategy interface { Apply(ctx *tcontext.Context, params Params, operateFn OperateFunc, - ) (interface{}, int, error) + ) (any, int, error) } // FiniteRetryStrategy will retry `RetryCount` times when failed to operate DB. @@ -79,7 +79,7 @@ type FiniteRetryStrategy struct{} // Apply for FiniteRetryStrategy, it waits `FirstRetryDuration` before it starts first retry, and then rest of retries wait time depends on BackoffStrategy. func (*FiniteRetryStrategy) Apply(ctx *tcontext.Context, params Params, operateFn OperateFunc, -) (ret interface{}, i int, err error) { +) (ret any, i int, err error) { for ; i < params.RetryCount; i++ { ret, err = operateFn(ctx) if err != nil { @@ -111,7 +111,7 @@ func (*FiniteRetryStrategy) Apply(ctx *tcontext.Context, params Params, operateF // Retryer retries operateFn until success or reaches retry limit // todo: merge with Strategy when refactor type Retryer interface { - Apply(ctx *tcontext.Context, operateFn OperateFunc) (interface{}, int, error) + Apply(ctx *tcontext.Context, operateFn OperateFunc) (any, int, error) } // FiniteRetryer wraps params. @@ -120,6 +120,6 @@ type FiniteRetryer struct { Params *Params } -func (s *FiniteRetryer) Apply(ctx *tcontext.Context, operateFn OperateFunc) (ret interface{}, i int, err error) { +func (s *FiniteRetryer) Apply(ctx *tcontext.Context, operateFn OperateFunc) (ret any, i int, err error) { return s.FiniteRetryStrategy.Apply(ctx, *s.Params, operateFn) } diff --git a/dm/pkg/retry/strategy_test.go b/dm/pkg/retry/strategy_test.go index b0b8e14017..2bc1e5a14e 100644 --- a/dm/pkg/retry/strategy_test.go +++ b/dm/pkg/retry/strategy_test.go @@ -38,7 +38,7 @@ func TestFiniteRetryStrategy(t *testing.T) { } ctx := tcontext.Background() - operateFn := func(*tcontext.Context) (interface{}, error) { + operateFn := func(*tcontext.Context) (any, error) { return nil, terror.ErrDBDriverError.Generate("test database error") } @@ -63,7 +63,7 @@ func TestFiniteRetryStrategy(t *testing.T) { params.IsRetryableFn = func(int, error) bool { return dbutil.IsRetryableError(err) } - operateFn = func(*tcontext.Context) (interface{}, error) { + operateFn = func(*tcontext.Context) (any, error) { mysqlErr := driver.ErrBadConn return nil, terror.ErrDBInvalidConn.Delegate(mysqlErr, "test invalid connection") } @@ -79,7 +79,7 @@ func TestFiniteRetryStrategy(t *testing.T) { require.True(t, terror.ErrDBInvalidConn.Equal(err)) retValue := "success" - operateFn = func(*tcontext.Context) (interface{}, error) { + operateFn = func(*tcontext.Context) (any, error) { return retValue, nil } ret, opCount, err := strategy.Apply(ctx, params, operateFn) diff --git a/dm/pkg/schema/tracker.go b/dm/pkg/schema/tracker.go index ea396ae245..5dc44b7480 100644 --- a/dm/pkg/schema/tracker.go +++ b/dm/pkg/schema/tracker.go @@ -105,7 +105,7 @@ func (se executorContext) GetRestrictedSQLExecutor() sqlexec.RestrictedSQLExecut return se } -func (se executorContext) ParseWithParams(context.Context, string, ...interface{}) (ast.StmtNode, error) { +func (se executorContext) ParseWithParams(context.Context, string, ...any) (ast.StmtNode, error) { return nil, nil } @@ -113,7 +113,7 @@ func (se executorContext) ExecRestrictedStmt(context.Context, ast.StmtNode, ...s return nil, nil, nil } -func (se executorContext) ExecRestrictedSQL(context.Context, []sqlexec.OptionFuncAlias, string, ...interface{}) ([]chunk.Row, []*resolve.ResultField, error) { +func (se executorContext) ExecRestrictedSQL(context.Context, []sqlexec.OptionFuncAlias, string, ...any) ([]chunk.Row, []*resolve.ResultField, error) { return nil, nil, nil } diff --git a/dm/pkg/schema/tracker_test.go b/dm/pkg/schema/tracker_test.go index fe31cfa923..9b19a23e27 100644 --- a/dm/pkg/schema/tracker_test.go +++ b/dm/pkg/schema/tracker_test.go @@ -359,7 +359,7 @@ func TestCreateTableIfNotExists(t *testing.T) { require.Equal(t, ti1, ti3, "ti3 = %s\nti1 = %s", asJSON{ti3}, asJSON{ti1}) start := time.Now() - for n := 0; n < 100; n++ { + for n := range 100 { err = tracker.CreateTableIfNotExists(&filter.Table{Schema: "testdb", Name: fmt.Sprintf("foo-%d", n)}, ti1) require.NoError(t, err) } diff --git a/dm/pkg/shardddl/optimism/keeper.go b/dm/pkg/shardddl/optimism/keeper.go index 2f2939890b..3f9c48a42d 100644 --- a/dm/pkg/shardddl/optimism/keeper.go +++ b/dm/pkg/shardddl/optimism/keeper.go @@ -14,6 +14,7 @@ package optimism import ( + "maps" "sort" "sync" @@ -165,9 +166,7 @@ func (lk *LockKeeper) Locks() map[string]*Lock { defer lk.mu.RUnlock() locks := make(map[string]*Lock, len(lk.locks)) - for k, v := range lk.locks { - locks[k] = v - } + maps.Copy(locks, lk.locks) return locks } @@ -208,9 +207,7 @@ func (tk *TableKeeper) Init(stm map[string]map[string]SourceTables) { if _, ok := tk.tables[task]; !ok { tk.tables[task] = make(map[string]SourceTables) } - for source, st := range sts { - tk.tables[task][source] = st - } + maps.Copy(tk.tables[task], sts) } } diff --git a/dm/pkg/shardddl/optimism/lock.go b/dm/pkg/shardddl/optimism/lock.go index fa2975bd59..deb5dffedf 100644 --- a/dm/pkg/shardddl/optimism/lock.go +++ b/dm/pkg/shardddl/optimism/lock.go @@ -18,6 +18,8 @@ import ( "context" "encoding/json" "fmt" + "maps" + "slices" "sync" "github.com/pingcap/errors" @@ -764,12 +766,7 @@ func GetColumnName(lockID, ddl string, tp ast.AlterTableType) (string, error) { } func contains(s []string, e string) bool { - for _, a := range s { - if a == e { - return true - } - } - return false + return slices.Contains(s, e) } // checkAddDropColumn check for ALTER TABLE ADD/DROP COLUMN statement @@ -1175,9 +1172,7 @@ func (l *Lock) resolveTables() { l.conflictTables = make(map[string]map[string]map[string]schemacmp.Table) for source, schemaTables := range l.finalTables { for schema, tables := range schemaTables { - for table, ti := range tables { - l.tables[source][schema][table] = ti - } + maps.Copy(l.tables[source][schema], tables) } } } diff --git a/dm/pkg/shardddl/optimism/lock_test.go b/dm/pkg/shardddl/optimism/lock_test.go index f952463d4c..c0988e695a 100644 --- a/dm/pkg/shardddl/optimism/lock_test.go +++ b/dm/pkg/shardddl/optimism/lock_test.go @@ -488,7 +488,7 @@ func (t *testLock) TestLockTrySyncNullNotNull(c *check.C) { t.checkLockSynced(c, l) t.checkLockNoDone(c, l) - for i := 0; i < 2; i++ { // two round + for range 2 { // two round // try sync for one table, from `NULL` to `NOT NULL`, no DDLs returned. info := newInfoWithVersion(task, source, db, tbls[0], downSchema, downTable, DDLs1, ti0, []*model.TableInfo{ti1}, vers) DDLs, cols, err := l.TrySync(info, tts) diff --git a/dm/pkg/shardddl/pessimism/info_test.go b/dm/pkg/shardddl/pessimism/info_test.go index 2fb67cd803..3293609b0f 100644 --- a/dm/pkg/shardddl/pessimism/info_test.go +++ b/dm/pkg/shardddl/pessimism/info_test.go @@ -119,13 +119,11 @@ func (t *testForEtcd) TestInfoEtcd(c *check.C) { ech := make(chan error, 10) ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { WatchInfoPut(ctx, etcdTestCli, rev4+1, wch, ech) // revision+1 close(wch) // close the chan close(ech) - }() + }) // put another key for a different task. _, err = PutInfo(etcdTestCli, i21) diff --git a/dm/pkg/shardddl/pessimism/keeper.go b/dm/pkg/shardddl/pessimism/keeper.go index ebfdbca978..f3c1a66c78 100644 --- a/dm/pkg/shardddl/pessimism/keeper.go +++ b/dm/pkg/shardddl/pessimism/keeper.go @@ -14,6 +14,7 @@ package pessimism import ( + "maps" "sync" "github.com/pingcap/tiflow/dm/master/metrics" @@ -85,9 +86,7 @@ func (lk *LockKeeper) Locks() map[string]*Lock { defer lk.mu.RUnlock() locks := make(map[string]*Lock, len(lk.locks)) - for k, v := range lk.locks { - locks[k] = v - } + maps.Copy(locks, lk.locks) return locks } diff --git a/dm/pkg/shardddl/pessimism/lock.go b/dm/pkg/shardddl/pessimism/lock.go index c7c9d5ee27..90a0a785a9 100644 --- a/dm/pkg/shardddl/pessimism/lock.go +++ b/dm/pkg/shardddl/pessimism/lock.go @@ -14,6 +14,7 @@ package pessimism import ( + "maps" "sync" "github.com/pingcap/tiflow/dm/master/metrics" @@ -137,9 +138,7 @@ func (l *Lock) Ready() map[string]bool { defer l.mu.RUnlock() ret := make(map[string]bool, len(l.ready)) - for k, v := range l.ready { - ret[k] = v - } + maps.Copy(ret, l.ready) return ret } diff --git a/dm/pkg/shardddl/pessimism/operation_test.go b/dm/pkg/shardddl/pessimism/operation_test.go index 80a012441d..609418e2ed 100644 --- a/dm/pkg/shardddl/pessimism/operation_test.go +++ b/dm/pkg/shardddl/pessimism/operation_test.go @@ -55,7 +55,7 @@ func watchExactOperations( <-done }() var ops []Operation - for i := 0; i < opCnt; i++ { + for range opCnt { select { case op := <-opCh: ops = append(ops, op) diff --git a/dm/pkg/storage/utils_test.go b/dm/pkg/storage/utils_test.go index e78f707de8..b24bb1c054 100644 --- a/dm/pkg/storage/utils_test.go +++ b/dm/pkg/storage/utils_test.go @@ -140,7 +140,6 @@ func TestStripS3ExternalID(t *testing.T) { } for _, tc := range cases { - tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() require.Equal(t, tc.want, StripS3ExternalID(tc.raw)) diff --git a/dm/pkg/terror/adapter.go b/dm/pkg/terror/adapter.go index d21261a8a4..a0248f2e3a 100644 --- a/dm/pkg/terror/adapter.go +++ b/dm/pkg/terror/adapter.go @@ -22,7 +22,7 @@ import ( // DBErrorAdaptArgs is an adapter to change raw database error to *Error object. // If err is already an *Error object, return it directly. -func DBErrorAdaptArgs(err error, defaultErr *Error, args ...interface{}) error { +func DBErrorAdaptArgs(err error, defaultErr *Error, args ...any) error { if err == nil { return nil } @@ -42,6 +42,6 @@ func DBErrorAdaptArgs(err error, defaultErr *Error, args ...interface{}) error { // DBErrorAdapt is an adapter to change raw database error to *Error object. // If err is already an *Error object, return it directly. -func DBErrorAdapt(err error, scope ErrScope, defaultErr *Error, args ...interface{}) error { +func DBErrorAdapt(err error, scope ErrScope, defaultErr *Error, args ...any) error { return WithScope(DBErrorAdaptArgs(err, defaultErr, args...), scope) } diff --git a/dm/pkg/terror/terror.go b/dm/pkg/terror/terror.go index 974a3a6094..de3a0933aa 100644 --- a/dm/pkg/terror/terror.go +++ b/dm/pkg/terror/terror.go @@ -155,7 +155,7 @@ type Error struct { level ErrLevel message string workaround string - args []interface{} + args []any rawCause error stack errors.StackTracer } @@ -279,7 +279,7 @@ func (e *Error) Equal(err error) bool { func (e *Error) SetMessage(message string) *Error { err := *e err.message = message - err.args = append([]interface{}{}, e.args...) + err.args = append([]any{}, e.args...) return &err } @@ -289,17 +289,17 @@ func (e *Error) New(message string) error { } // Generate generates a new *Error with the same class and code, and new arguments. -func (e *Error) Generate(args ...interface{}) error { +func (e *Error) Generate(args ...any) error { return e.stackLevelGeneratef(1, e.message, args...) } // Generatef generates a new *Error with the same class and code, and a new formatted message. -func (e *Error) Generatef(format string, args ...interface{}) error { +func (e *Error) Generatef(format string, args ...any) error { return e.stackLevelGeneratef(1, format, args...) } // stackLevelGeneratef is an inner interface to generate new *Error. -func (e *Error) stackLevelGeneratef(stackSkipLevel int, format string, args ...interface{}) error { +func (e *Error) stackLevelGeneratef(stackSkipLevel int, format string, args ...any) error { return &Error{ code: e.code, class: e.class, @@ -314,7 +314,7 @@ func (e *Error) stackLevelGeneratef(stackSkipLevel int, format string, args ...i // Delegate creates a new *Error with the same fields of the give *Error, // except for new arguments, it also sets the err as raw cause of *Error. -func (e *Error) Delegate(err error, args ...interface{}) error { +func (e *Error) Delegate(err error, args ...any) error { if err == nil { return nil } @@ -339,7 +339,7 @@ func (e *Error) Delegate(err error, args ...interface{}) error { } // AnnotateDelegate resets the message of *Error and Delegate with error and new args. -func (e *Error) AnnotateDelegate(err error, message string, args ...interface{}) error { +func (e *Error) AnnotateDelegate(err error, message string, args ...any) error { if err == nil { return nil } @@ -362,7 +362,7 @@ func Annotate(err error, message string) error { } // Annotatef tries to convert err to *Error and adds a message to it. -func Annotatef(err error, format string, args ...interface{}) error { +func Annotatef(err error, format string, args ...any) error { if err == nil { return nil } diff --git a/dm/pkg/terror/terror_test.go b/dm/pkg/terror/terror_test.go index a08efd014a..f50b12ef3e 100644 --- a/dm/pkg/terror/terror_test.go +++ b/dm/pkg/terror/terror_test.go @@ -60,7 +60,7 @@ func TestTError(t *testing.T) { setMsgErr := err.SetMessage(messageArgs) require.Equal(t, messageArgs, setMsgErr.getMsg()) - setMsgErr.args = []interface{}{"1062"} + setMsgErr.args = []any{"1062"} require.Equal(t, fmt.Sprintf(messageArgs, setMsgErr.args...), setMsgErr.getMsg()) // test Error Generate/Generatef @@ -141,12 +141,12 @@ func TestTErrorStackTrace(t *testing.T) { testCases := []struct { fn string message string - args []interface{} + args []any stackFingerprint string }{ {"new", "new error", nil, ".*\\(\\*Error\\)\\.New"}, - {"generate", "", []interface{}{"parma1"}, ".*\\(\\*Error\\)\\.Generate"}, - {"generatef", "generatef error %s %d", []interface{}{"param1", 12}, ".*\\(\\*Error\\)\\.Generatef"}, + {"generate", "", []any{"parma1"}, ".*\\(\\*Error\\)\\.Generate"}, + {"generatef", "generatef error %s %d", []any{"param1", 12}, ".*\\(\\*Error\\)\\.Generatef"}, } for _, tc := range testCases { diff --git a/dm/pkg/upgrade/upgrade_test.go b/dm/pkg/upgrade/upgrade_test.go index 225ae9b56f..cdc8b4a20c 100644 --- a/dm/pkg/upgrade/upgrade_test.go +++ b/dm/pkg/upgrade/upgrade_test.go @@ -169,7 +169,7 @@ func (t *testForEtcd) TestUpgradeToVer3(c *check.C) { c.Assert(resp.Kvs, check.HasLen, 1) c.Assert(string(resp.Kvs[0].Value), check.Equals, newVal) - for i := 0; i < 500; i++ { + for i := range 500 { key := common.UpstreamConfigKeyAdapterV1.Encode(fmt.Sprintf("%s-%d", source, i)) val := fmt.Sprintf("%s-%d", oldVal, i) _, err := etcdTestCli.Put(ctx, key, val) @@ -183,7 +183,7 @@ func (t *testForBigTxn) TestUpgradeToVer3(c *check.C) { oldVal := "test" ctx := context.Background() - for i := 0; i < 1000; i++ { + for i := range 1000 { key := common.UpstreamConfigKeyAdapterV1.Encode(fmt.Sprintf("%s-%d", source, i)) val := fmt.Sprintf("%s-%d", oldVal, i) _, err := bigTxnTestCli.Put(ctx, key, val) diff --git a/dm/pkg/utils/common.go b/dm/pkg/utils/common.go index 1326097afe..1c21556005 100644 --- a/dm/pkg/utils/common.go +++ b/dm/pkg/utils/common.go @@ -154,7 +154,7 @@ type session struct { sessionctx.Context vars *variable.SessionVars exprctx exprctx.ExprContext - values map[fmt.Stringer]interface{} + values map[fmt.Stringer]any builtinFunctionUsage map[string]uint32 mu sync.RWMutex } @@ -169,14 +169,14 @@ func (se *session) GetExprCtx() exprctx.ExprContext { } // SetValue implements the sessionctx.Context interface. -func (se *session) SetValue(key fmt.Stringer, value interface{}) { +func (se *session) SetValue(key fmt.Stringer, value any) { se.mu.Lock() se.values[key] = value se.mu.Unlock() } // Value implements the sessionctx.Context interface. -func (se *session) Value(key fmt.Stringer) interface{} { +func (se *session) Value(key fmt.Stringer) any { se.mu.RLock() value := se.values[key] se.mu.RUnlock() @@ -211,7 +211,7 @@ func NewSessionCtx(vars map[string]string) sessionctx.Context { } sessionCtx := session{ vars: variables, - values: make(map[fmt.Stringer]interface{}, 1), + values: make(map[fmt.Stringer]any, 1), builtinFunctionUsage: make(map[string]uint32), } sessionCtx.exprctx = sessionexpr.NewExprContext(&sessionCtx) @@ -219,7 +219,7 @@ func NewSessionCtx(vars map[string]string) sessionctx.Context { } // AdjustBinaryProtocolForDatum converts the data in binlog to TiDB datum. -func AdjustBinaryProtocolForDatum(ctx sessionctx.Context, data []interface{}, cols []*model.ColumnInfo) ([]types.Datum, error) { +func AdjustBinaryProtocolForDatum(ctx sessionctx.Context, data []any, cols []*model.ColumnInfo) ([]types.Datum, error) { ret := make([]types.Datum, 0, len(data)) for i, d := range data { datum := types.NewDatum(d) diff --git a/dm/pkg/utils/common_test.go b/dm/pkg/utils/common_test.go index 7511e1b656..4f70b9d8c6 100644 --- a/dm/pkg/utils/common_test.go +++ b/dm/pkg/utils/common_test.go @@ -30,7 +30,7 @@ func TestTrimCtrlChars(t *testing.T) { ddl := "create table if not exists foo.bar(id int)" controlChars := make([]byte, 0, 33) nul := byte(0x00) - for i := 0; i < 32; i++ { + for range 32 { controlChars = append(controlChars, nul) nul++ } diff --git a/dm/pkg/utils/string.go b/dm/pkg/utils/string.go index dc01756a3d..a18faec7d0 100644 --- a/dm/pkg/utils/string.go +++ b/dm/pkg/utils/string.go @@ -37,7 +37,7 @@ func TruncateString(s string, n int) string { // and returns a string with only the leading (at most) n runes of the input string. // If the converted string is truncated, a `...` tail will be appended. // It is not effective for large structure now. -func TruncateInterface(v interface{}, n int) string { +func TruncateInterface(v any, n int) string { return TruncateString(fmt.Sprintf("%+v", v), n) } diff --git a/dm/pkg/utils/string_test.go b/dm/pkg/utils/string_test.go index df60aba4d1..15a404f082 100644 --- a/dm/pkg/utils/string_test.go +++ b/dm/pkg/utils/string_test.go @@ -56,12 +56,12 @@ func TestTruncateInterface(t *testing.T) { i2 = compose{b: true, i: 456, s: "def"} i3 = compose{b: false, i: 321, s: "cba"} i4 = compose{b: false, i: 654, s: "fed"} - iis [][]interface{} + iis [][]any ) - iis = append(iis, []interface{}{i1, i2}, []interface{}{i3, i4}) + iis = append(iis, []any{i1, i2}, []any{i3, i4}) cases := []struct { - v interface{} + v any n int expect string }{ diff --git a/dm/pkg/utils/util.go b/dm/pkg/utils/util.go index eae77809c3..39ab69abcb 100644 --- a/dm/pkg/utils/util.go +++ b/dm/pkg/utils/util.go @@ -129,7 +129,7 @@ func DecodeBinlogPosition(pos string) (*mysql.Position, error) { // WaitSomething waits for something done with `true`. func WaitSomething(backoff int, waitTime time.Duration, fn func() bool) bool { - for i := 0; i < backoff; i++ { + for range backoff { if fn() { return true } diff --git a/dm/pkg/utils/util_test.go b/dm/pkg/utils/util_test.go index a6447afd25..6da48ba66e 100644 --- a/dm/pkg/utils/util_test.go +++ b/dm/pkg/utils/util_test.go @@ -302,7 +302,7 @@ func TestProxyFields(t *testing.T) { require.NoError(t, os.Unsetenv(env)) } - for i := 0; i < 3; i++ { + for i := range 3 { if (1< m.nextOp { - newStartIdx = m.nextOp - } + newStartIdx := min(m.minIdxLargerOrEqual(pos), m.nextOp) m.ops = m.ops[newStartIdx:] m.nextOp -= newStartIdx diff --git a/dm/syncer/binlogstream/streamer_controller_test.go b/dm/syncer/binlogstream/streamer_controller_test.go index 597be52f0d..2a1e8d3910 100644 --- a/dm/syncer/binlogstream/streamer_controller_test.go +++ b/dm/syncer/binlogstream/streamer_controller_test.go @@ -69,7 +69,7 @@ func TestCanErrorRetry(t *testing.T) { mockErr := errors.New("test") // local binlog puller can always retry - for i := 0; i < 5; i++ { + for range 5 { require.True(t, controller.CanRetry(mockErr)) } diff --git a/dm/syncer/causality_test.go b/dm/syncer/causality_test.go index db7390c4d3..6c74b087f8 100644 --- a/dm/syncer/causality_test.go +++ b/dm/syncer/causality_test.go @@ -86,24 +86,24 @@ func TestCausality(t *testing.T) { syncer.metricsProxies = metrics.DefaultMetricsProxies.CacheForOneTask("task", "worker", "source") causalityCh := causalityWrap(jobCh, syncer) testCases := []struct { - preVals []interface{} - postVals []interface{} + preVals []any + postVals []any }{ { - postVals: []interface{}{1, 2}, + postVals: []any{1, 2}, }, { - postVals: []interface{}{2, 3}, + postVals: []any{2, 3}, }, { - preVals: []interface{}{2, 3}, - postVals: []interface{}{3, 4}, + preVals: []any{2, 3}, + postVals: []any{3, 4}, }, { - preVals: []interface{}{1, 2}, + preVals: []any{1, 2}, }, { - postVals: []interface{}{1, 3}, + postVals: []any{1, 3}, }, } results := []opType{dml, dml, dml, dml, conflict, dml} @@ -195,7 +195,7 @@ func (s *testSyncerSuite) TestCasualityRelation(c *check.C) { c.Assert(rmMap.prevFlushJobSeq, check.Not(check.Equals), int64(index)) } - for ti := 0; ti < index; ti++ { + for ti := range index { _, ok := rm.get(testCases[ti].key) c.Assert(ok, check.Equals, false) } diff --git a/dm/syncer/checkpoint.go b/dm/syncer/checkpoint.go index d227c64c0e..bf7b9b9f59 100644 --- a/dm/syncer/checkpoint.go +++ b/dm/syncer/checkpoint.go @@ -277,7 +277,7 @@ type CheckPoint interface { // by extraSQLs and extraArgs. Currently extraSQLs contain shard meta only. // @exceptTables: [[schema, table]... ] // corresponding to Meta.Flush - FlushPointsExcept(tctx *tcontext.Context, snapshotID int, exceptTables []*filter.Table, extraSQLs []string, extraArgs [][]interface{}) error + FlushPointsExcept(tctx *tcontext.Context, snapshotID int, exceptTables []*filter.Table, extraSQLs []string, extraArgs [][]any) error // FlushPointsWithTableInfos flushed the table points with given table infos FlushPointsWithTableInfos(tctx *tcontext.Context, tables []*filter.Table, tis []*model.TableInfo) error @@ -518,7 +518,7 @@ func (cp *RemoteCheckPoint) Clear(tctx *tcontext.Context) error { tctx2, cp.metricProxies, []string{`DELETE FROM ` + cp.tableName + ` WHERE id = ?`}, - []interface{}{cp.id}, + []any{cp.id}, ) if err != nil { return err @@ -599,7 +599,7 @@ func (cp *RemoteCheckPoint) DeleteTablePoint(tctx *tcontext.Context, table *filt tctx2, cp.metricProxies, []string{`DELETE FROM ` + cp.tableName + ` WHERE id = ? AND cp_schema = ? AND cp_table = ?`}, - []interface{}{cp.id, sourceSchema, sourceTable}, + []any{cp.id, sourceSchema, sourceTable}, ) if err != nil { return err @@ -620,7 +620,7 @@ func (cp *RemoteCheckPoint) DeleteAllTablePoint(tctx *tcontext.Context) error { tctx2, cp.metricProxies, []string{`DELETE FROM ` + cp.tableName + ` WHERE id = ? AND is_global = ?`}, - []interface{}{cp.id, false}, + []any{cp.id, false}, ) if err != nil { return err @@ -645,7 +645,7 @@ func (cp *RemoteCheckPoint) DeleteSchemaPoint(tctx *tcontext.Context, sourceSche tctx2, cp.metricProxies, []string{`DELETE FROM ` + cp.tableName + ` WHERE id = ? AND cp_schema = ?`}, - []interface{}{cp.id, sourceSchema}, + []any{cp.id, sourceSchema}, ) if err != nil { return err @@ -707,7 +707,7 @@ func (cp *RemoteCheckPoint) FlushPointsExcept( snapshotID int, exceptTables []*filter.Table, extraSQLs []string, - extraArgs [][]interface{}, + extraArgs [][]any, ) error { cp.Lock() @@ -730,7 +730,7 @@ func (cp *RemoteCheckPoint) FlushPointsExcept( } sqls := make([]string, 0, 100) - args := make([][]interface{}, 0, 100) + args := make([][]any, 0, 100) type tableCpSnapshotTuple struct { tableCp *binlogPoint // current table checkpoint location @@ -813,13 +813,10 @@ func (cp *RemoteCheckPoint) FlushPointsWithTableInfos(tctx *tcontext.Context, ta } for i := 0; i < len(tables); i += batchFlushPoints { - end := i + batchFlushPoints - if end > len(tables) { - end = len(tables) - } + end := min(i+batchFlushPoints, len(tables)) sqls := make([]string, 0, batchFlushPoints) - args := make([][]interface{}, 0, batchFlushPoints) + args := make([][]any, 0, batchFlushPoints) points := make([]*binlogPoint, 0, batchFlushPoints) for j := i; j < end; j++ { table := tables[j] @@ -872,7 +869,7 @@ func (cp *RemoteCheckPoint) FlushSafeModeExitPoint(tctx *tcontext.Context) error defer cp.RUnlock() sqls := make([]string, 1) - args := make([][]interface{}, 1) + args := make([][]any, 1) // use FlushedGlobalPoint here to avoid update global checkpoint locationG := cp.FlushedGlobalPoint() @@ -995,8 +992,8 @@ func (cp *RemoteCheckPoint) prepare(tctx *tcontext.Context) error { func (cp *RemoteCheckPoint) createSchema(tctx *tcontext.Context) error { // TODO(lance6716): change ColumnName to IdentName or something sql2 := fmt.Sprintf("CREATE SCHEMA IF NOT EXISTS %s", dbutil.ColumnName(cp.cfg.MetaSchema)) - args := make([]interface{}, 0) - _, err := cp.dbConn.ExecuteSQL(tctx, cp.metricProxies, []string{sql2}, [][]interface{}{args}...) + args := make([]any, 0) + _, err := cp.dbConn.ExecuteSQL(tctx, cp.metricProxies, []string{sql2}, [][]any{args}...) cp.logCtx.L().Info("create checkpoint schema", zap.String("statement", sql2)) return err } @@ -1254,7 +1251,7 @@ func (cp *RemoteCheckPoint) LoadMeta(ctx context.Context) error { } // genUpdateSQL generates SQL and arguments for update checkpoint. -func (cp *RemoteCheckPoint) genUpdateSQL(cpSchema, cpTable string, location binlog.Location, safeModeExitLoc *binlog.Location, tiBytes []byte, isGlobal bool) (string, []interface{}) { +func (cp *RemoteCheckPoint) genUpdateSQL(cpSchema, cpTable string, location binlog.Location, safeModeExitLoc *binlog.Location, tiBytes []byte, isGlobal bool) (string, []any) { // use `INSERT INTO ... ON DUPLICATE KEY UPDATE` rather than `REPLACE INTO` // to keep `create_time`, `update_time` correctly sql2 := `INSERT INTO ` + cp.tableName + ` @@ -1292,7 +1289,7 @@ func (cp *RemoteCheckPoint) genUpdateSQL(cpSchema, cpTable string, location binl } // convert tiBytes to string to get a readable log - args := []interface{}{ + args := []any{ cp.id, cpSchema, cpTable, location.Position.Name, location.Position.Pos, location.GTIDSetStr(), exitSafeName, exitSafePos, exitSafeGTIDStr, string(tiBytes), isGlobal, } diff --git a/dm/syncer/checkpoint_flush_worker.go b/dm/syncer/checkpoint_flush_worker.go index 403424782d..2380d810ad 100644 --- a/dm/syncer/checkpoint_flush_worker.go +++ b/dm/syncer/checkpoint_flush_worker.go @@ -30,7 +30,7 @@ type checkpointFlushTask struct { // extra sharding ddl sqls exceptTables []*filter.Table shardMetaSQLs []string - shardMetaArgs [][]interface{} + shardMetaArgs [][]any // async flush job asyncflushJob *job // error chan for sync flush diff --git a/dm/syncer/checkpoint_test.go b/dm/syncer/checkpoint_test.go index 22159d2570..a8ec200b7a 100644 --- a/dm/syncer/checkpoint_test.go +++ b/dm/syncer/checkpoint_test.go @@ -260,8 +260,8 @@ func (s *testCheckpointSuite) testGlobalCheckPoint(c *check.C, cp CheckPoint) { dir := c.MkDir() filename := filepath.Join(dir, "metadata") - err = os.WriteFile(filename, []byte( - fmt.Sprintf("SHOW MASTER STATUS:\n\tLog: %s\n\tPos: %d\n\tGTID:\n\nSHOW SLAVE STATUS:\n\tHost: %s\n\tLog: %s\n\tPos: %d\n\tGTID:\n\n", pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000)), + err = os.WriteFile(filename, + fmt.Appendf(nil, "SHOW MASTER STATUS:\n\tLog: %s\n\tPos: %d\n\tGTID:\n\nSHOW SLAVE STATUS:\n\tHost: %s\n\tLog: %s\n\tPos: %d\n\tGTID:\n\n", pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000), 0o644) c.Assert(err, check.IsNil) s.cfg.Mode = config.ModeAll @@ -285,8 +285,8 @@ func (s *testCheckpointSuite) testGlobalCheckPoint(c *check.C, cp CheckPoint) { c.Assert(err, check.IsNil) // check dumpling write exitSafeModeLocation in metadata - err = os.WriteFile(filename, []byte( - fmt.Sprintf(`SHOW MASTER STATUS: + err = os.WriteFile(filename, + fmt.Appendf(nil, `SHOW MASTER STATUS: Log: %s Pos: %d GTID: @@ -301,7 +301,7 @@ SHOW MASTER STATUS: /* AFTER CONNECTION POOL ESTABLISHED */ Log: %s Pos: %d GTID: -`, pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000, pos2.Name, pos2.Pos)), 0o644) +`, pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000, pos2.Name, pos2.Pos), 0o644) c.Assert(err, check.IsNil) c.Assert(cp.LoadMeta(tctx.Ctx), check.IsNil) @@ -539,14 +539,14 @@ func TestRemoteCheckPointLoadIntoSchemaTracker(t *testing.T) { // create 100K comment string comment := make([]byte, 0, 100000) - for i := 0; i < 100000; i++ { + for range 100000 { comment = append(comment, 'A') } ti.Comment = string(comment) tp1 = tablePoint{ti: ti} amount := 100 - for i := 0; i < amount; i++ { + for i := range amount { tableName := fmt.Sprintf("tbl_%d", i) checkpoint.points[tbl1.Schema][tableName] = &binlogPoint{flushedPoint: tp1} } diff --git a/dm/syncer/compactor_test.go b/dm/syncer/compactor_test.go index 406f0db206..404d24851a 100644 --- a/dm/syncer/compactor_test.go +++ b/dm/syncer/compactor_test.go @@ -34,7 +34,7 @@ import ( ) // mockExecute mock a kv store. -func mockExecute(kv map[interface{}][]interface{}, dmls []*sqlmodel.RowChange) map[interface{}][]interface{} { +func mockExecute(kv map[any][]any, dmls []*sqlmodel.RowChange) map[any][]any { for _, dml := range dmls { switch dml.Type() { case sqlmodel.RowChangeInsert: @@ -86,12 +86,12 @@ func (s *testSyncerSuite) TestCompactJob(c *check.C) { updateIdentifyProbability := 0.1 // generate DMLs - kv := make(map[interface{}][]interface{}) - for i := 0; i < dmlNum; i++ { + kv := make(map[any][]any) + for range dmlNum { newID := rand.Intn(maxID) newCol1 := rand.Intn(maxID * 10) newName := randString(rand.Intn(20)) - values := []interface{}{newID, newCol1, newName} + values := []any{newID, newCol1, newName} oldValues, ok := kv[newID] if !ok { // insert @@ -101,7 +101,7 @@ func (s *testSyncerSuite) TestCompactJob(c *check.C) { // update // check whether to update ID if rand.Float64() < updateIdentifyProbability { - for try := 0; try < 10; try++ { + for range 10 { newID := rand.Intn(maxID) if _, ok := kv[newID]; !ok { values[0] = newID @@ -120,15 +120,12 @@ func (s *testSyncerSuite) TestCompactJob(c *check.C) { dmls = append(dmls, dml) } - kv = make(map[interface{}][]interface{}) - compactKV := make(map[interface{}][]interface{}) + kv = make(map[any][]any) + compactKV := make(map[any][]any) // mock compactJob for i := 0; i < len(dmls); i += batch { - end := i + batch - if end > len(dmls) { - end = len(dmls) - } + end := min(i+batch, len(dmls)) kv = mockExecute(kv, dmls[i:end]) for _, dml := range dmls[i:end] { @@ -184,37 +181,37 @@ func (s *testSyncerSuite) TestCompactorSafeMode(c *check.C) { { input: []*job{ newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{1, 1, "a"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{1, 1, "a"}, ti, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{2, 2, "b"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{2, 2, "b"}, ti, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, []interface{}{1, 1, "a"}, []interface{}{3, 3, "c"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, []any{1, 1, "a"}, []any{3, 3, "c"}, ti, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, []interface{}{2, 2, "b"}, nil, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, []any{2, 2, "b"}, nil, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{1, 1, "a"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{1, 1, "a"}, ti, nil, nil), ec, ), }, output: []*job{ newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{3, 3, "c"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{3, 3, "c"}, ti, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, []interface{}{2, 2, "b"}, nil, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, []any{2, 2, "b"}, nil, ti, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{1, 1, "a"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{1, 1, "a"}, ti, nil, nil), ecWithSafeMode, ), }, @@ -223,45 +220,45 @@ func (s *testSyncerSuite) TestCompactorSafeMode(c *check.C) { { input: []*job{ newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{1, 1, "a"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{1, 1, "a"}, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{2, 2, "b"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{2, 2, "b"}, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, []interface{}{1, 1, "a"}, []interface{}{3, 3, "c"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, []any{1, 1, "a"}, []any{3, 3, "c"}, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, []interface{}{2, 2, "b"}, nil, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, []any{2, 2, "b"}, nil, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{1, 1, "a"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{1, 1, "a"}, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{2, 2, "b"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{2, 2, "b"}, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, []interface{}{2, 2, "b"}, []interface{}{2, 2, "c"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, []any{2, 2, "b"}, []any{2, 2, "c"}, ti, nil, nil), ec, ), }, output: []*job{ newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{3, 3, "c"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{3, 3, "c"}, ti, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{1, 1, "a"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{1, 1, "a"}, ti, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable, nil, nil, []interface{}{2, 2, "c"}, ti, nil, nil), + sqlmodel.NewRowChange(sourceTable, nil, nil, []any{2, 2, "c"}, ti, nil, nil), ecWithSafeMode, ), }, diff --git a/dm/syncer/data_validator.go b/dm/syncer/data_validator.go index aea64576e4..59548d3ff8 100644 --- a/dm/syncer/data_validator.go +++ b/dm/syncer/data_validator.go @@ -470,11 +470,9 @@ func (v *DataValidator) errorProcessRoutine() { if errors.Cause(err) != context.Canceled && !stopped { stopped = true - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { v.stopInner() - }() + }) } } wg.Wait() @@ -915,7 +913,7 @@ func (v *DataValidator) processRowsEvent(header *replication.EventHeader, ev *re } estimatedRowSize := int32(header.EventSize) / int32(len(ev.Rows)) for i := 0; i < len(ev.Rows); i += step { - var beforeImage, afterImage []interface{} + var beforeImage, afterImage []any switch changeType { case rowInsert: afterImage = ev.Rows[i] @@ -1043,7 +1041,7 @@ func (v *DataValidator) loadPersistedData() error { // aggregate using target table just as worker did. pendingChanges[validateTbl.targetTable.String()] = pendingTblChange for _, row := range tblChange.rows { - var beforeImage, afterImage []interface{} + var beforeImage, afterImage []any switch row.Tp { case rowInsert: afterImage = row.Data diff --git a/dm/syncer/data_validator_test.go b/dm/syncer/data_validator_test.go index 27dfc3e72d..a9a466406d 100644 --- a/dm/syncer/data_validator_test.go +++ b/dm/syncer/data_validator_test.go @@ -225,7 +225,7 @@ func TestValidatorDeadLock(t *testing.T) { // nolint:errcheck recover() }() - for i := 0; i < 100; i++ { + for range 100 { validator.sendError(context.Canceled) // prevent from stopping the validator } }() @@ -383,7 +383,7 @@ func TestValidatorProcessRowsEventAdjustUnsignedData(t *testing.T) { Table: []byte(tableName), }, ColumnCount: 2, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(-2061521730), "v1"}, }, }, @@ -489,7 +489,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(1), "a"}, {int32(2), "b"}, {int32(3), "c"}, @@ -501,7 +501,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName2, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(1), "a"}, {int32(2), "b"}, {int32(3), "c"}, @@ -513,7 +513,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName3, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(1), "a"}, {int32(2), "b"}, {int32(3), "c"}, @@ -525,7 +525,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName3, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(4), "a"}, }, }, @@ -536,7 +536,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ // update non-primary column {int32(3), "c"}, {int32(3), "d"}, @@ -552,7 +552,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(3), "c"}, }, }, @@ -562,7 +562,7 @@ func TestValidatorDoValidate(t *testing.T) { Schema: schemaName, Table: tableName4, ColumnType: []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, - Rows: [][]interface{}{ + Rows: [][]any{ {int32(4), "c"}, }, }, @@ -648,7 +648,7 @@ func TestValidatorGenRowKey(t *testing.T) { require.Equal(t, "a\tb", genRowKeyByString([]string{"a", "b"})) require.Equal(t, "a\tb\tc", genRowKeyByString([]string{"a", "b", "c"})) var bytes []byte - for i := 0; i < 100; i++ { + for range 100 { bytes = append(bytes, 'a') } { @@ -886,13 +886,11 @@ func TestValidatorErrorProcessRoutineDeadlock(t *testing.T) { finishedCh := make(chan struct{}) // simulate a worker - validator.wg.Add(1) - go func() { - defer validator.wg.Done() + validator.wg.Go(func() { validator.sendError(errors.New("test error 1")) validator.sendError(errors.New("test error 2")) validator.sendError(errors.New("test error 3")) - }() + }) validator.errProcessWg.Add(1) go func() { diff --git a/dm/syncer/dbconn/db.go b/dm/syncer/dbconn/db.go index 7b5f26b5ea..4477b567fe 100644 --- a/dm/syncer/dbconn/db.go +++ b/dm/syncer/dbconn/db.go @@ -88,7 +88,7 @@ func (conn *DBConn) QuerySQL( tctx *tcontext.Context, metricProxies *metrics.Proxies, query string, - args ...interface{}, + args ...any, ) (*sql.Rows, error) { if conn == nil || conn.baseConn == nil { return nil, terror.ErrDBUnExpect.Generate("database base connection not valid") @@ -104,7 +104,7 @@ func (conn *DBConn) QuerySQL( ret, _, err := conn.baseConn.ApplyRetryStrategy( tctx, params, - func(ctx *tcontext.Context) (interface{}, error) { + func(ctx *tcontext.Context) (any, error) { startTime := time.Now() ret, err := conn.baseConn.QuerySQL(ctx, query, args...) if err == nil { @@ -143,7 +143,7 @@ func (conn *DBConn) ExecuteSQLWithIgnore( metricProxies *metrics.Proxies, ignoreError func(error) bool, queries []string, - args ...[]interface{}, + args ...[]any, ) (int, error) { failpoint.Inject("ExecuteSQLWithIgnoreFailed", func(val failpoint.Value) { queryPattern := val.(string) @@ -173,7 +173,7 @@ func (conn *DBConn) ExecuteSQLWithIgnore( ret, numRetries, err := conn.baseConn.ApplyRetryStrategy( tctx, params, - func(ctx *tcontext.Context) (interface{}, error) { + func(ctx *tcontext.Context) (any, error) { startTime := time.Now() var histProxy *prometheus.HistogramVec if metricProxies != nil { @@ -218,7 +218,7 @@ func (conn *DBConn) ExecuteSQL( tctx *tcontext.Context, metricProxies *metrics.Proxies, queries []string, - args ...[]interface{}, + args ...[]any, ) (int, error) { return conn.ExecuteSQLWithIgnore(tctx, metricProxies, nil, queries, args...) } @@ -229,7 +229,7 @@ func (conn *DBConn) ExecuteSQLAutoSplit( tctx *tcontext.Context, metricProxies *metrics.Proxies, queries []string, - args ...[]interface{}, + args ...[]any, ) error { if conn == nil { // only happens in test @@ -261,7 +261,7 @@ func (conn *DBConn) retryableFn(tctx *tcontext.Context, queries, args any) func( _, resetRetries, resetErr := conn.baseConn.ApplyRetryStrategy( tctx, resetRetryParams, - func(ctx *tcontext.Context) (interface{}, error) { + func(ctx *tcontext.Context) (any, error) { err = conn.ResetConn(tctx) return nil, err }) @@ -330,7 +330,7 @@ func CreateConns(tctx *tcontext.Context, cfg *config.SubTaskConfig, dbCfg conn.S if err != nil { return nil, nil, err } - for i := 0; i < count; i++ { + for range count { baseConn, err := baseDB.GetBaseConn(tctx.Context()) if err != nil { CloseBaseDB(tctx, baseDB) diff --git a/dm/syncer/dml.go b/dm/syncer/dml.go index 8a20915796..0f3e9e9705 100644 --- a/dm/syncer/dml.go +++ b/dm/syncer/dml.go @@ -38,9 +38,9 @@ type genDMLParam struct { sourceTable *filter.Table // origin table targetTable *filter.Table safeMode bool // only used in update - originalData [][]interface{} // all data + originalData [][]any // all data sourceTableInfo *model.TableInfo // all table info - extendData [][]interface{} // all data include extend data + extendData [][]any // all data include extend data } // latin1Decider is not usually ISO8859_1 in MySQL. @@ -51,10 +51,10 @@ var latin1Decoder = charmap.Windows1252.NewDecoder() // - the values can be correctly converted to TiDB datum // - the values are in the correct type that go-sql-driver/mysql uses. func adjustValueFromBinlogData( - data []interface{}, + data []any, sourceTI *model.TableInfo, -) ([]interface{}, error) { - value := make([]interface{}, 0, len(data)) +) ([]any, error) { + value := make([]any, 0, len(data)) var err error columns := make([]*model.ColumnInfo, 0, len(sourceTI.Columns)) @@ -329,7 +329,7 @@ func (s *Syncer) causalityKeySourceTableNameForRowChange(sourceTable *filter.Tab } } -func castUnsigned(data interface{}, ft *types.FieldType) interface{} { +func castUnsigned(data any, ft *types.FieldType) any { if !mysql.HasUnsignedFlag(ft.GetFlag()) { return data } @@ -371,7 +371,7 @@ func checkLogColumns(skipped [][]int) error { } // genSQLMultipleRows generates multiple rows SQL with different dmlOpType. -func genSQLMultipleRows(op sqlmodel.DMLType, dmls []*sqlmodel.RowChange) (queries string, args []interface{}) { +func genSQLMultipleRows(op sqlmodel.DMLType, dmls []*sqlmodel.RowChange) (queries string, args []any) { if len(dmls) > 1 { log.L().Debug("generate DMLs with multiple rows", zap.Stringer("op", op), zap.Stringer("original op", dmls[0].Type()), zap.Int("rows", len(dmls))) } @@ -393,12 +393,12 @@ func genSQLMultipleRows(op sqlmodel.DMLType, dmls []*sqlmodel.RowChange) (querie // insert into tb(a,b,d) values(2,2,2) // we can only combine DMLs with same column names. // all dmls should have same dmlOpType and same tableName. -func genDMLsWithSameCols(op sqlmodel.DMLType, dmls []*sqlmodel.RowChange) ([]string, [][]interface{}) { +func genDMLsWithSameCols(op sqlmodel.DMLType, dmls []*sqlmodel.RowChange) ([]string, [][]any) { queries := make([]string, 0, len(dmls)) - args := make([][]interface{}, 0, len(dmls)) + args := make([][]any, 0, len(dmls)) var lastDML *sqlmodel.RowChange var query string - var arg []interface{} + var arg []any groupDMLs := make([]*sqlmodel.RowChange, 0, len(dmls)) // group dmls by same columns @@ -426,9 +426,9 @@ func genDMLsWithSameCols(op sqlmodel.DMLType, dmls []*sqlmodel.RowChange) ([]str // genDMLsWithSameTable groups and generates dmls with same table. // all the dmls should have same dmlOpType. -func genDMLsWithSameTable(op sqlmodel.DMLType, jobs []*job) ([]string, [][]interface{}) { +func genDMLsWithSameTable(op sqlmodel.DMLType, jobs []*job) ([]string, [][]any) { queries := make([]string, 0, len(jobs)) - args := make([][]interface{}, 0, len(jobs)) + args := make([][]any, 0, len(jobs)) var lastTable string groupDMLs := make([]*sqlmodel.RowChange, 0, len(jobs)) @@ -492,9 +492,9 @@ func genDMLsWithSameTable(op sqlmodel.DMLType, jobs []*job) ([]string, [][]inter // genDMLsWithSameOp groups and generates dmls by dmlOpType. // TODO: implement a volcano iterator interface for genDMLsWithSameXXX. -func genDMLsWithSameOp(jobs []*job) ([]string, [][]interface{}) { +func genDMLsWithSameOp(jobs []*job) ([]string, [][]any) { queries := make([]string, 0, len(jobs)) - args := make([][]interface{}, 0, len(jobs)) + args := make([][]any, 0, len(jobs)) var lastOp sqlmodel.DMLType jobsWithSameOp := make([]*job, 0, len(jobs)) diff --git a/dm/syncer/dml_test.go b/dm/syncer/dml_test.go index c15cc1899e..fea22a10f8 100644 --- a/dm/syncer/dml_test.go +++ b/dm/syncer/dml_test.go @@ -44,10 +44,10 @@ func TestCastUnsigned(t *testing.T) { // ref: https://dev.mysql.com/doc/refman/5.7/en/integer-types.html cases := []struct { - data interface{} + data any unsigned bool Type byte - expected interface{} + expected any }{ {int8(-math.Exp2(7)), false, mysql.TypeTiny, int8(-math.Exp2(7))}, // TINYINT {int8(-math.Exp2(7)), true, mysql.TypeTiny, uint8(math.Exp2(7))}, @@ -96,156 +96,156 @@ func TestGenDMLWithSameOp(t *testing.T) { dmls := []*job{ // insert newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, nil, []interface{}{1, 1, "a"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, nil, []any{1, 1, "a"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, nil, []interface{}{2, 2, "b"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, nil, []any{2, 2, "b"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable12, targetTable1, nil, []interface{}{3, 3, "c"}, tableInfo12, nil, nil), + sqlmodel.NewRowChange(sourceTable12, targetTable1, nil, []any{3, 3, "c"}, tableInfo12, nil, nil), ecWithSafeMode, ), // update no index but safemode newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{1, 1, "a"}, []interface{}{1, 1, "aa"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{1, 1, "a"}, []any{1, 1, "aa"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{2, 2, "b"}, []interface{}{2, 2, "bb"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{2, 2, "b"}, []any{2, 2, "bb"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable12, targetTable1, []interface{}{3, 3, "c"}, []interface{}{3, 3, "cc"}, tableInfo12, nil, nil), + sqlmodel.NewRowChange(sourceTable12, targetTable1, []any{3, 3, "c"}, []any{3, 3, "cc"}, tableInfo12, nil, nil), ecWithSafeMode, ), // update uk newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{1, 1, "aa"}, []interface{}{1, 4, "aa"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{1, 1, "aa"}, []any{1, 4, "aa"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{2, 2, "bb"}, []interface{}{2, 5, "bb"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{2, 2, "bb"}, []any{2, 5, "bb"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable12, targetTable1, []interface{}{3, 3, "cc"}, []interface{}{3, 6, "cc"}, tableInfo12, nil, nil), + sqlmodel.NewRowChange(sourceTable12, targetTable1, []any{3, 3, "cc"}, []any{3, 6, "cc"}, tableInfo12, nil, nil), ecWithSafeMode, ), // update pk newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{1, 4, "aa"}, []interface{}{4, 4, "aa"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{1, 4, "aa"}, []any{4, 4, "aa"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{2, 5, "bb"}, []interface{}{5, 5, "bb"}, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{2, 5, "bb"}, []any{5, 5, "bb"}, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable12, targetTable1, []interface{}{3, 6, "cc"}, []interface{}{6, 6, "cc"}, tableInfo12, nil, nil), + sqlmodel.NewRowChange(sourceTable12, targetTable1, []any{3, 6, "cc"}, []any{6, 6, "cc"}, tableInfo12, nil, nil), ecWithSafeMode, ), // delete newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{4, 4, "aa"}, nil, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{4, 4, "aa"}, nil, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{5, 5, "bb"}, nil, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{5, 5, "bb"}, nil, tableInfo11, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable12, targetTable1, []interface{}{6, 6, "cc"}, nil, tableInfo12, nil, nil), + sqlmodel.NewRowChange(sourceTable12, targetTable1, []any{6, 6, "cc"}, nil, tableInfo12, nil, nil), ecWithSafeMode, ), // target table 2 // insert newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, nil, []interface{}{1, 1, "a"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, nil, []any{1, 1, "a"}, tableInfo21, nil, nil), ecWithSafeMode, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, nil, []interface{}{2, 2, "b"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, nil, []any{2, 2, "b"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable22, targetTable2, nil, []interface{}{3, 3, "c"}, tableInfo22, nil, nil), + sqlmodel.NewRowChange(sourceTable22, targetTable2, nil, []any{3, 3, "c"}, tableInfo22, nil, nil), ec, ), // update no index newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{1, 1, "a"}, []interface{}{1, 1, "aa"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{1, 1, "a"}, []any{1, 1, "aa"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{2, 2, "b"}, []interface{}{2, 2, "bb"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{2, 2, "b"}, []any{2, 2, "bb"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable22, targetTable2, []interface{}{3, 3, "c"}, []interface{}{3, 3, "cc"}, tableInfo22, nil, nil), + sqlmodel.NewRowChange(sourceTable22, targetTable2, []any{3, 3, "c"}, []any{3, 3, "cc"}, tableInfo22, nil, nil), ec, ), // update uk newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{1, 1, "aa"}, []interface{}{1, 4, "aa"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{1, 1, "aa"}, []any{1, 4, "aa"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{2, 2, "bb"}, []interface{}{2, 5, "bb"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{2, 2, "bb"}, []any{2, 5, "bb"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable22, targetTable2, []interface{}{3, 3, "cc"}, []interface{}{3, 6, "cc"}, tableInfo22, nil, nil), + sqlmodel.NewRowChange(sourceTable22, targetTable2, []any{3, 3, "cc"}, []any{3, 6, "cc"}, tableInfo22, nil, nil), ec, ), // update pk newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{1, 4, "aa"}, []interface{}{4, 4, "aa"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{1, 4, "aa"}, []any{4, 4, "aa"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{2, 5, "bb"}, []interface{}{5, 5, "bb"}, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{2, 5, "bb"}, []any{5, 5, "bb"}, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable22, targetTable2, []interface{}{3, 6, "cc"}, []interface{}{6, 6, "cc"}, tableInfo22, nil, nil), + sqlmodel.NewRowChange(sourceTable22, targetTable2, []any{3, 6, "cc"}, []any{6, 6, "cc"}, tableInfo22, nil, nil), ec, ), // delete newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{4, 4, "aa"}, nil, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{4, 4, "aa"}, nil, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable21, targetTable2, []interface{}{5, 5, "bb"}, nil, tableInfo21, nil, nil), + sqlmodel.NewRowChange(sourceTable21, targetTable2, []any{5, 5, "bb"}, nil, tableInfo21, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable22, targetTable2, []interface{}{6, 6, "cc"}, nil, tableInfo22, nil, nil), + sqlmodel.NewRowChange(sourceTable22, targetTable2, []any{6, 6, "cc"}, nil, tableInfo22, nil, nil), ec, ), // table1 // detele newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{44, 44, "aaa"}, nil, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{44, 44, "aaa"}, nil, tableInfo11, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable11, targetTable1, []interface{}{55, 55, "bbb"}, nil, tableInfo11, nil, nil), + sqlmodel.NewRowChange(sourceTable11, targetTable1, []any{55, 55, "bbb"}, nil, tableInfo11, nil, nil), ec, ), newDMLJob( - sqlmodel.NewRowChange(sourceTable12, targetTable1, []interface{}{66, 66, "ccc"}, nil, tableInfo12, nil, nil), + sqlmodel.NewRowChange(sourceTable12, targetTable1, []any{66, 66, "ccc"}, nil, tableInfo12, nil, nil), ec, ), } @@ -286,7 +286,7 @@ func TestGenDMLWithSameOp(t *testing.T) { "DELETE FROM `db1`.`tb1` WHERE (`id` = ?) OR (`id` = ?) OR (`id` = ?)", } - expectArgs := [][]interface{}{ + expectArgs := [][]any{ // table1 {1, 1, "a", 2, 2, "b", 3, 3, "c"}, {1, 1, "aa"}, @@ -336,8 +336,8 @@ func TestGBKExtractValueFromData(t *testing.T) { ti, err := createTableInfo(p, se, 0, table) require.NoError(t, err) - row := []interface{}{1, "\xc4\xe3\xba\xc3"} - expect := []interface{}{1, []byte("\xc4\xe3\xba\xc3")} + row := []any{1, "\xc4\xe3\xba\xc3"} + expect := []any{1, []byte("\xc4\xe3\xba\xc3")} got, err := adjustValueFromBinlogData(row, ti) require.NoError(t, err) require.Equal(t, expect, got) diff --git a/dm/syncer/dml_worker.go b/dm/syncer/dml_worker.go index 848d000459..0e770d029f 100644 --- a/dm/syncer/dml_worker.go +++ b/dm/syncer/dml_worker.go @@ -258,7 +258,7 @@ func (w *DMLWorker) executeBatchJobs(queueID int, jobs []*job, disableForeignKey var ( affect int queries []string - args [][]interface{} + args [][]any db = w.toDBConns[queueID] err error dmls = make([]*sqlmodel.RowChange, 0, len(jobs)) @@ -375,16 +375,16 @@ func (w *DMLWorker) setForeignKeyChecks(queueID int, enable bool) error { } // genSQLs generate SQLs in single row mode or multiple rows mode. -func (w *DMLWorker) genSQLs(jobs []*job) ([]string, [][]interface{}) { +func (w *DMLWorker) genSQLs(jobs []*job) ([]string, [][]any) { if w.multipleRows { return genDMLsWithSameOp(jobs) } queries := make([]string, 0, len(jobs)) - args := make([][]interface{}, 0, len(jobs)) + args := make([][]any, 0, len(jobs)) for _, j := range jobs { var query string - var arg []interface{} + var arg []any appendQueryAndArg := func() { queries = append(queries, query) args = append(args, arg) diff --git a/dm/syncer/dml_worker_test.go b/dm/syncer/dml_worker_test.go index dc3c94bab9..42131666b4 100644 --- a/dm/syncer/dml_worker_test.go +++ b/dm/syncer/dml_worker_test.go @@ -55,60 +55,60 @@ func TestGenSQL(t *testing.T) { createSQL := "create table db.tb(id int primary key, col1 int unique not null, col2 int unique, name varchar(24))" cases := []struct { - preValues []interface{} - postValues []interface{} + preValues []any + postValues []any safeMode bool expectedSQLs []string - expectedArgs [][]interface{} + expectedArgs [][]any }{ { nil, - []interface{}{1, 2, 3, "haha"}, + []any{1, 2, 3, "haha"}, false, []string{"INSERT INTO `targetSchema`.`targetTable` (`id`,`col1`,`col2`,`name`) VALUES (?,?,?,?)"}, - [][]interface{}{{1, 2, 3, "haha"}}, + [][]any{{1, 2, 3, "haha"}}, }, { nil, - []interface{}{1, 2, 3, "haha"}, + []any{1, 2, 3, "haha"}, true, []string{"REPLACE INTO `targetSchema`.`targetTable` (`id`,`col1`,`col2`,`name`) VALUES (?,?,?,?)"}, - [][]interface{}{{1, 2, 3, "haha"}}, + [][]any{{1, 2, 3, "haha"}}, }, { - []interface{}{1, 2, 3, "haha"}, + []any{1, 2, 3, "haha"}, nil, false, []string{"DELETE FROM `targetSchema`.`targetTable` WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{1}}, + [][]any{{1}}, }, { - []interface{}{1, 2, 3, "haha"}, - []interface{}{4, 5, 6, "hihi"}, + []any{1, 2, 3, "haha"}, + []any{4, 5, 6, "hihi"}, false, []string{"UPDATE `targetSchema`.`targetTable` SET `id` = ?, `col1` = ?, `col2` = ?, `name` = ? WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{4, 5, 6, "hihi", 1}}, + [][]any{{4, 5, 6, "hihi", 1}}, }, { - []interface{}{1, 2, 3, "haha"}, - []interface{}{1, 2, 3, "hihi"}, + []any{1, 2, 3, "haha"}, + []any{1, 2, 3, "hihi"}, true, []string{"REPLACE INTO `targetSchema`.`targetTable` (`id`,`col1`,`col2`,`name`) VALUES (?,?,?,?)"}, - [][]interface{}{{1, 2, 3, "hihi"}}, + [][]any{{1, 2, 3, "hihi"}}, }, { - []interface{}{1, 2, 3, "haha"}, - []interface{}{4, 5, 6, "hihi"}, + []any{1, 2, 3, "haha"}, + []any{4, 5, 6, "hihi"}, true, []string{"DELETE FROM `targetSchema`.`targetTable` WHERE `id` = ? LIMIT 1", "REPLACE INTO `targetSchema`.`targetTable` (`id`,`col1`,`col2`,`name`) VALUES (?,?,?,?)"}, - [][]interface{}{{1}, {4, 5, 6, "hihi"}}, + [][]any{{1}, {4, 5, 6, "hihi"}}, }, } @@ -155,18 +155,18 @@ func TestShouldDisableForeignKeyChecksForJob(t *testing.T) { target := &cdcmodel.TableName{Schema: "target", Table: "tb"} tableInfo := mockTableInfo(t, "create table db.tb(id int primary key, name varchar(10))") - insertChange := sqlmodel.NewRowChange(source, target, nil, []interface{}{1, "v"}, tableInfo, nil, nil) + insertChange := sqlmodel.NewRowChange(source, target, nil, []any{1, "v"}, tableInfo, nil, nil) insertJob := &job{tp: dml, safeMode: true, dml: insertChange} require.False(t, worker.shouldDisableForeignKeyChecksForJob(insertJob)) worker.foreignKeyChecksEnabled = true require.True(t, worker.shouldDisableForeignKeyChecksForJob(insertJob)) - updateChange := sqlmodel.NewRowChange(source, target, []interface{}{1, "a"}, []interface{}{1, "b"}, tableInfo, nil, nil) + updateChange := sqlmodel.NewRowChange(source, target, []any{1, "a"}, []any{1, "b"}, tableInfo, nil, nil) updateJob := &job{tp: dml, safeMode: true, dml: updateChange} require.True(t, worker.shouldDisableForeignKeyChecksForJob(updateJob)) - deleteChange := sqlmodel.NewRowChange(source, target, []interface{}{1, "a"}, nil, tableInfo, nil, nil) + deleteChange := sqlmodel.NewRowChange(source, target, []any{1, "a"}, nil, tableInfo, nil, nil) deleteJob := &job{tp: dml, safeMode: true, dml: deleteChange} require.False(t, worker.shouldDisableForeignKeyChecksForJob(deleteJob)) @@ -182,18 +182,18 @@ func TestShouldDisableForeignKeyChecks(t *testing.T) { target := &cdcmodel.TableName{Schema: "target", Table: "tbl"} tableInfo := mockTableInfo(t, "create table db.tb(id int primary key, col1 int unique not null, col2 int unique, name varchar(24))") - insertChange := sqlmodel.NewRowChange(source, target, nil, []interface{}{1, 2, 3, "v"}, tableInfo, nil, nil) + insertChange := sqlmodel.NewRowChange(source, target, nil, []any{1, 2, 3, "v"}, tableInfo, nil, nil) insertJob := newDMLJob(insertChange, ecWithSafeMode) require.True(t, worker.shouldDisableForeignKeyChecksForJob(insertJob)) insertJob.safeMode = false require.False(t, worker.shouldDisableForeignKeyChecksForJob(insertJob)) - updateChange := sqlmodel.NewRowChange(source, target, []interface{}{1, 2, 3, "v"}, []interface{}{1, 2, 3, "v2"}, tableInfo, nil, nil) + updateChange := sqlmodel.NewRowChange(source, target, []any{1, 2, 3, "v"}, []any{1, 2, 3, "v2"}, tableInfo, nil, nil) updateJob := newDMLJob(updateChange, ecWithSafeMode) require.True(t, worker.shouldDisableForeignKeyChecksForJob(updateJob)) - deleteChange := sqlmodel.NewRowChange(source, target, []interface{}{1, 2, 3, "v"}, nil, tableInfo, nil, nil) + deleteChange := sqlmodel.NewRowChange(source, target, []any{1, 2, 3, "v"}, nil, tableInfo, nil, nil) deleteJob := newDMLJob(deleteChange, ecWithSafeMode) require.False(t, worker.shouldDisableForeignKeyChecksForJob(deleteJob)) @@ -217,24 +217,24 @@ func TestValidateSafeModeForeignKeyUpdate(t *testing.T) { // PK change pkUpdate := sqlmodel.NewRowChange( source, target, - []interface{}{1, "a", "x"}, - []interface{}{2, "a", "x"}, + []any{1, "a", "x"}, + []any{2, "a", "x"}, tableInfo, nil, nil, ) // UK change ukUpdate := sqlmodel.NewRowChange( source, target, - []interface{}{1, "a", "x"}, - []interface{}{1, "b", "x"}, + []any{1, "a", "x"}, + []any{1, "b", "x"}, tableInfo, nil, nil, ) // Non-key change nonKeyUpdate := sqlmodel.NewRowChange( source, target, - []interface{}{1, "a", "x"}, - []interface{}{1, "a", "y"}, + []any{1, "a", "x"}, + []any{1, "a", "y"}, tableInfo, nil, nil, ) @@ -267,7 +267,7 @@ func TestExecuteBatchJobsWithForeignKey(t *testing.T) { t.Parallel() // helper: convert []interface{} -> []driver.Value - toDriverValues := func(args []interface{}) []driver.Value { + toDriverValues := func(args []any) []driver.Value { out := make([]driver.Value, len(args)) for i, v := range args { out[i] = v @@ -302,8 +302,8 @@ func TestExecuteBatchJobsWithForeignKey(t *testing.T) { createSQL := "create table db.tb(id int primary key, col1 int unique not null, col2 int unique, name varchar(24))" tableInfo := mockTableInfo(t, createSQL) - insertChange := sqlmodel.NewRowChange(source, target, nil, []interface{}{1, 2, 3, "normal"}, tableInfo, nil, nil) - replaceChange := sqlmodel.NewRowChange(source, target, nil, []interface{}{2, 3, 4, "safe"}, tableInfo, nil, nil) + insertChange := sqlmodel.NewRowChange(source, target, nil, []any{1, 2, 3, "normal"}, tableInfo, nil, nil) + replaceChange := sqlmodel.NewRowChange(source, target, nil, []any{2, 3, 4, "safe"}, tableInfo, nil, nil) insertJob := newDMLJob(insertChange, ec) replaceJob := newDMLJob(replaceChange, ecWithSafeMode) diff --git a/dm/syncer/expr_filter_group.go b/dm/syncer/expr_filter_group.go index 8335b2c873..4e418f1f6e 100644 --- a/dm/syncer/expr_filter_group.go +++ b/dm/syncer/expr_filter_group.go @@ -179,7 +179,7 @@ func (g *ExprFilterGroup) ResetExprs(table *filter.Table) { } // SkipDMLByExpression returns true when given row matches the expr, which means this row should be skipped. -func SkipDMLByExpression(ctx sessionctx.Context, row []interface{}, expr expression.Expression, upstreamCols []*model.ColumnInfo) (bool, error) { +func SkipDMLByExpression(ctx sessionctx.Context, row []any, expr expression.Expression, upstreamCols []*model.ColumnInfo) (bool, error) { // TODO: add MetricsProxies data, err := utils.AdjustBinaryProtocolForDatum(ctx, row, upstreamCols) if err != nil { diff --git a/dm/syncer/expr_filter_group_test.go b/dm/syncer/expr_filter_group_test.go index 459dc73f75..dbf13f4303 100644 --- a/dm/syncer/expr_filter_group_test.go +++ b/dm/syncer/expr_filter_group_test.go @@ -36,8 +36,8 @@ func TestSkipDMLByExpression(t *testing.T) { cases := []struct { exprStr string tableStr string - skippedRow []interface{} - passedRow []interface{} + skippedRow []any + passedRow []any }{ { "state != 1", @@ -50,8 +50,8 @@ create table t ( UNIQUE KEY uniq_id (id), KEY idx_state (state) );`, - []interface{}{100, 100, 3}, - []interface{}{100, 100, 1}, + []any{100, 100, 3}, + []any{100, 100, 1}, }, { "f > 1.23", @@ -59,8 +59,8 @@ create table t ( create table t ( f float );`, - []interface{}{float32(2.0)}, - []interface{}{float32(1.0)}, + []any{float32(2.0)}, + []any{float32(1.0)}, }, { "f > a + b", @@ -70,8 +70,8 @@ create table t ( a int, b int );`, - []interface{}{float32(123.45), 1, 2}, - []interface{}{float32(0.01), 23, 45}, + []any{float32(123.45), 1, 2}, + []any{float32(0.01), 23, 45}, }, { "id = 30", @@ -83,8 +83,8 @@ create table t ( ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) );`, - []interface{}{int32(30), "30", nil, "2021-06-17 10:13:05"}, - []interface{}{int32(20), "20", nil, "2021-06-17 10:13:05"}, + []any{int32(30), "30", nil, "2021-06-17 10:13:05"}, + []any{int32(20), "20", nil, "2021-06-17 10:13:05"}, }, } @@ -143,8 +143,8 @@ func TestAllBinaryProtocolTypes(t *testing.T) { cases := []struct { exprStr string tableStr string - skippedRow []interface{} - passedRow []interface{} + skippedRow []any + passedRow []any }{ // MYSQL_TYPE_NULL { @@ -153,8 +153,8 @@ func TestAllBinaryProtocolTypes(t *testing.T) { create table t ( c int );`, - []interface{}{nil}, - []interface{}{100}, + []any{nil}, + []any{100}, }, // MYSQL_TYPE_LONG { @@ -163,8 +163,8 @@ create table t ( create table t ( c int );`, - []interface{}{int32(1)}, - []interface{}{int32(100)}, + []any{int32(1)}, + []any{int32(100)}, }, // MYSQL_TYPE_TINY { @@ -173,8 +173,8 @@ create table t ( create table t ( c tinyint );`, - []interface{}{int8(2)}, - []interface{}{int8(-1)}, + []any{int8(2)}, + []any{int8(-1)}, }, // MYSQL_TYPE_SHORT { @@ -183,8 +183,8 @@ create table t ( create table t ( c smallint );`, - []interface{}{int16(8)}, - []interface{}{int16(18)}, + []any{int16(8)}, + []any{int16(18)}, }, // MYSQL_TYPE_INT24 { @@ -193,8 +193,8 @@ create table t ( create table t ( c mediumint );`, - []interface{}{int32(-8)}, - []interface{}{int32(1)}, + []any{int32(-8)}, + []any{int32(1)}, }, // MYSQL_TYPE_LONGLONG { @@ -203,8 +203,8 @@ create table t ( create table t ( c bigint );`, - []interface{}{int64(100000000)}, - []interface{}{int64(200000000)}, + []any{int64(100000000)}, + []any{int64(200000000)}, }, // MYSQL_TYPE_NEWDECIMAL { @@ -213,8 +213,8 @@ create table t ( create table t ( c decimal(5,2) );`, - []interface{}{"10.10"}, - []interface{}{"10.11"}, + []any{"10.10"}, + []any{"10.11"}, }, // MYSQL_TYPE_FLOAT { @@ -223,8 +223,8 @@ create table t ( create table t ( c float );`, - []interface{}{float32(0.08)}, - []interface{}{float32(0.18)}, + []any{float32(0.08)}, + []any{float32(0.18)}, }, // MYSQL_TYPE_DOUBLE { @@ -233,8 +233,8 @@ create table t ( create table t ( c double );`, - []interface{}{float64(0.08)}, - []interface{}{float64(0.18)}, + []any{float64(0.08)}, + []any{float64(0.18)}, }, // MYSQL_TYPE_BIT { @@ -243,8 +243,8 @@ create table t ( create table t ( c bit(4) );`, - []interface{}{int64(1)}, - []interface{}{int64(2)}, + []any{int64(1)}, + []any{int64(2)}, }, // MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP2 // DM does not set ParseTime @@ -255,8 +255,8 @@ create table t ( create table t ( c timestamp );`, - []interface{}{"2021-06-21 12:34:56"}, - []interface{}{"1970-01-01 00:00:01"}, + []any{"2021-06-21 12:34:56"}, + []any{"1970-01-01 00:00:01"}, }, // MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME2 { @@ -265,8 +265,8 @@ create table t ( create table t ( c datetime );`, - []interface{}{"2021-06-21 00:00:12"}, - []interface{}{"1970-01-01 00:00:01"}, + []any{"2021-06-21 00:00:12"}, + []any{"1970-01-01 00:00:01"}, }, // MYSQL_TYPE_TIME, MYSQL_TYPE_TIME2 { @@ -275,8 +275,8 @@ create table t ( create table t ( c time(6) );`, - []interface{}{"00:00:12"}, - []interface{}{"00:00:01"}, + []any{"00:00:12"}, + []any{"00:00:01"}, }, // MYSQL_TYPE_DATE { @@ -285,8 +285,8 @@ create table t ( create table t ( c date );`, - []interface{}{"2021-06-21"}, - []interface{}{"1970-01-01"}, + []any{"2021-06-21"}, + []any{"1970-01-01"}, }, // MYSQL_TYPE_YEAR { @@ -295,8 +295,8 @@ create table t ( create table t ( c year );`, - []interface{}{int(2021)}, - []interface{}{int(2020)}, + []any{int(2021)}, + []any{int(2020)}, }, // MYSQL_TYPE_ENUM { @@ -305,8 +305,8 @@ create table t ( create table t ( c ENUM('x-small', 'small', 'medium', 'large', 'x-large') );`, - []interface{}{int64(1)}, // 1-indexed - []interface{}{int64(2)}, + []any{int64(1)}, // 1-indexed + []any{int64(2)}, }, // MYSQL_TYPE_SET { @@ -315,8 +315,8 @@ create table t ( create table t ( c SET('a', 'b', 'c', 'd') );`, - []interface{}{int64(0b1100)}, // c,d - []interface{}{int64(0b1000)}, // d + []any{int64(0b1100)}, // c,d + []any{int64(0b1000)}, // d }, // MYSQL_TYPE_BLOB { @@ -325,8 +325,8 @@ create table t ( create table t ( c blob );`, - []interface{}{[]byte("\x124")}, // x'1234' - []interface{}{[]byte("Vx")}, // x'5678' + []any{[]byte("\x124")}, // x'1234' + []any{[]byte("Vx")}, // x'5678' }, // MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING { @@ -335,8 +335,8 @@ create table t ( create table t ( c varchar(20) );`, - []interface{}{"abc"}, - []interface{}{"def"}, + []any{"abc"}, + []any{"def"}, }, // MYSQL_TYPE_JSON { @@ -345,8 +345,8 @@ create table t ( create table t ( c json );`, - []interface{}{[]byte(`{"id": 1}`)}, - []interface{}{[]byte(`{"id": 2}`)}, + []any{[]byte(`{"id": 1}`)}, + []any{[]byte(`{"id": 2}`)}, }, // MYSQL_TYPE_GEOMETRY, parser not supported } @@ -445,10 +445,10 @@ create table t ( require.Equal(t, "0", expr.StringWithCtx(context2.EmptyParamValues, errors.RedactLogDisable)) // skip nothing - skip, err := SkipDMLByExpression(sessCtx, []interface{}{0}, expr, ti.Columns) + skip, err := SkipDMLByExpression(sessCtx, []any{0}, expr, ti.Columns) require.NoError(t, err) require.False(t, skip) - skip, err = SkipDMLByExpression(sessCtx, []interface{}{2}, expr, ti.Columns) + skip, err = SkipDMLByExpression(sessCtx, []any{2}, expr, ti.Columns) require.NoError(t, err) require.False(t, skip) } diff --git a/dm/syncer/job_test.go b/dm/syncer/job_test.go index 03519901e6..8839267fe8 100644 --- a/dm/syncer/job_test.go +++ b/dm/syncer/job_test.go @@ -84,7 +84,7 @@ func TestJob(t *testing.T) { schema := "create table test.tb(id int primary key, col1 int unique not null)" ti := mockTableInfo(t, schema) - exampleChange := sqlmodel.NewRowChange(table, nil, nil, []interface{}{2, 2}, ti, nil, nil) + exampleChange := sqlmodel.NewRowChange(table, nil, nil, []any{2, 2}, ti, nil, nil) testCases := []struct { job *job diff --git a/dm/syncer/online-ddl-tools/online_ddl.go b/dm/syncer/online-ddl-tools/online_ddl.go index 8902e0c1ba..3690b9e93d 100644 --- a/dm/syncer/online-ddl-tools/online_ddl.go +++ b/dm/syncer/online-ddl-tools/online_ddl.go @@ -254,7 +254,7 @@ func (s *Storage) saveToDB(tctx *tcontext.Context, ghostSchema, ghostTable strin } query := fmt.Sprintf("REPLACE INTO %s(`id`,`ghost_schema`, `ghost_table`, `ddls`) VALUES (?, ?, ?, ?)", s.tableName) - _, err = s.dbConn.ExecuteSQL(tctx, s.metricProxies, []string{query}, []interface{}{s.id, ghostSchema, ghostTable, string(ddlsBytes)}) + _, err = s.dbConn.ExecuteSQL(tctx, s.metricProxies, []string{query}, []any{s.id, ghostSchema, ghostTable, string(ddlsBytes)}) failpoint.Inject("ExitAfterSaveOnlineDDL", func() { tctx.L().Info("failpoint ExitAfterSaveOnlineDDL") panic("ExitAfterSaveOnlineDDL") @@ -277,7 +277,7 @@ func (s *Storage) delete(tctx *tcontext.Context, ghostSchema, ghostTable string) // delete all checkpoints sql := fmt.Sprintf("DELETE FROM %s WHERE `id` = ? and `ghost_schema` = ? and `ghost_table` = ?", s.tableName) - _, err := s.dbConn.ExecuteSQL(tctx, s.metricProxies, []string{sql}, []interface{}{s.id, ghostSchema, ghostTable}) + _, err := s.dbConn.ExecuteSQL(tctx, s.metricProxies, []string{sql}, []any{s.id, ghostSchema, ghostTable}) if err != nil { return terror.WithScope(err, terror.ScopeDownstream) } @@ -293,7 +293,7 @@ func (s *Storage) Clear(tctx *tcontext.Context) error { // delete all checkpoints sql := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", s.tableName) - _, err := s.dbConn.ExecuteSQL(tctx, s.metricProxies, []string{sql}, []interface{}{s.id}) + _, err := s.dbConn.ExecuteSQL(tctx, s.metricProxies, []string{sql}, []any{s.id}) if err != nil { return terror.WithScope(err, terror.ScopeDownstream) } diff --git a/dm/syncer/shardddl/optimist.go b/dm/syncer/shardddl/optimist.go index 94707693a7..01ea2acbf5 100644 --- a/dm/syncer/shardddl/optimist.go +++ b/dm/syncer/shardddl/optimist.go @@ -217,7 +217,7 @@ func (o *Optimist) GetRedirectOperation(ctx context.Context, info optimism.Info, // DoneOperation marks the shard DDL lock operation as done. func (o *Optimist) DoneOperation(op optimism.Operation) error { op.Done = true - _, _, err := etcdutil.DoTxnWithRepeatable(o.cli, func(_ *tcontext.Context, cli *clientv3.Client) (interface{}, error) { + _, _, err := etcdutil.DoTxnWithRepeatable(o.cli, func(_ *tcontext.Context, cli *clientv3.Client) (any, error) { _, _, err := optimism.PutOperation(cli, false, op, 0) return nil, err }) diff --git a/dm/syncer/shardddl/pessimist.go b/dm/syncer/shardddl/pessimist.go index 2011fdd3b4..a2dc528b51 100644 --- a/dm/syncer/shardddl/pessimist.go +++ b/dm/syncer/shardddl/pessimist.go @@ -134,7 +134,7 @@ func (p *Pessimist) GetOperation(ctx context.Context, info pessimism.Info, rev i func (p *Pessimist) DoneOperationDeleteInfo(op pessimism.Operation, info pessimism.Info) error { op.Done = true // mark the operation as `done`. - _, _, err := etcdutil.DoTxnWithRepeatable(p.cli, func(_ *tcontext.Context, cli *clientv3.Client) (interface{}, error) { + _, _, err := etcdutil.DoTxnWithRepeatable(p.cli, func(_ *tcontext.Context, cli *clientv3.Client) (any, error) { done, _, err := pessimism.PutOperationDeleteExistInfo(cli, op, info) if err != nil { return nil, err diff --git a/dm/syncer/sharding-meta/shardmeta.go b/dm/syncer/sharding-meta/shardmeta.go index 1b4246ef21..3a23839d8b 100644 --- a/dm/syncer/sharding-meta/shardmeta.go +++ b/dm/syncer/sharding-meta/shardmeta.go @@ -257,34 +257,34 @@ func (meta *ShardingMeta) ActiveDDLFirstLocation() (binlog.Location, error) { } // FlushData returns sharding meta flush SQL and args. -func (meta *ShardingMeta) FlushData(sourceID, tableID string) ([]string, [][]interface{}) { +func (meta *ShardingMeta) FlushData(sourceID, tableID string) ([]string, [][]any) { if len(meta.global.Items) == 0 { sql2 := fmt.Sprintf("DELETE FROM %s where source_id=? and target_table_id=?", meta.tableName) - args2 := []interface{}{sourceID, tableID} - return []string{sql2}, [][]interface{}{args2} + args2 := []any{sourceID, tableID} + return []string{sql2}, [][]any{args2} } var ( sqls = make([]string, 1+len(meta.sources)) - args = make([][]interface{}, 0, 1+len(meta.sources)) + args = make([][]any, 0, 1+len(meta.sources)) baseSQL = fmt.Sprintf("INSERT INTO %s (`source_id`, `target_table_id`, `source_table_id`, `active_index`, `is_global`, `data`) VALUES(?,?,?,?,?,?) ON DUPLICATE KEY UPDATE `data`=?, `active_index`=?", meta.tableName) ) for i := range sqls { sqls[i] = baseSQL } - args = append(args, []interface{}{sourceID, tableID, "", meta.activeIdx, true, meta.global.String(), meta.global.String(), meta.activeIdx}) + args = append(args, []any{sourceID, tableID, "", meta.activeIdx, true, meta.global.String(), meta.global.String(), meta.activeIdx}) for source, seq := range meta.sources { - args = append(args, []interface{}{sourceID, tableID, source, meta.activeIdx, false, seq.String(), seq.String(), meta.activeIdx}) + args = append(args, []any{sourceID, tableID, source, meta.activeIdx, false, seq.String(), seq.String(), meta.activeIdx}) } return sqls, args } -func (meta *ShardingMeta) genRemoveSQL(sourceID, tableID string) (string, []interface{}) { +func (meta *ShardingMeta) genRemoveSQL(sourceID, tableID string) (string, []any) { sql := fmt.Sprintf("DELETE FROM %s where source_id=? and target_table_id=?", meta.tableName) - return sql, []interface{}{sourceID, tableID} + return sql, []any{sourceID, tableID} } // CheckAndUpdate check and fix schema and table names for all the sharding groups. -func (meta *ShardingMeta) CheckAndUpdate(logger log.Logger, targetID string, schemaMap map[string]string, tablesMap map[string]map[string]string) ([]string, [][]interface{}, error) { +func (meta *ShardingMeta) CheckAndUpdate(logger log.Logger, targetID string, schemaMap map[string]string, tablesMap map[string]map[string]string) ([]string, [][]any, error) { if len(schemaMap) == 0 && len(tablesMap) == 0 { return nil, nil, nil } @@ -330,7 +330,7 @@ func (meta *ShardingMeta) CheckAndUpdate(logger log.Logger, targetID string, sch } var ( sqls []string - args [][]interface{} + args [][]any ) for oldID, newID := range sourceIDsMap { if oldID != newID { diff --git a/dm/syncer/sharding-meta/shardmeta_test.go b/dm/syncer/sharding-meta/shardmeta_test.go index a662e904d7..c9018a2f1d 100644 --- a/dm/syncer/sharding-meta/shardmeta_test.go +++ b/dm/syncer/sharding-meta/shardmeta_test.go @@ -35,7 +35,7 @@ func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { active bool err error sqls []string - args [][]interface{} + args [][]any location binlog.Location filename = "mysql-bin.000001" table1 = "table1" @@ -60,7 +60,7 @@ func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { ) // 1st round sharding DDL sync - for i := 0; i < 7; i++ { + for i := range 7 { active, err = meta.AddItem(items[i]) c.Assert(err, check.IsNil) if i%3 == 0 { @@ -104,7 +104,7 @@ func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { } // 2nd round sharding DDL sync - for i := 0; i < 8; i++ { + for i := range 8 { if i%3 == 0 { continue } @@ -150,7 +150,7 @@ func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { } // 3rd round sharding DDL sync - for i := 0; i < 9; i++ { + for i := range 9 { if i%3 != 2 { continue } @@ -186,7 +186,7 @@ func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { c.Assert(sqls, check.HasLen, 1) c.Assert(args, check.HasLen, 1) c.Assert(sqls[0], check.Matches, "DELETE FROM .*") - c.Assert(args[0], check.DeepEquals, []interface{}{sourceID, tableID}) + c.Assert(args[0], check.DeepEquals, []any{sourceID, tableID}) } func (t *testShardMetaSuite) TestShardingMetaWrongSequence(c *check.C) { @@ -208,7 +208,7 @@ func (t *testShardMetaSuite) TestShardingMetaWrongSequence(c *check.C) { ) // 1st round sharding DDL sync - for i := 0; i < 4; i++ { + for i := range 4 { active, err = meta.AddItem(items[i]) c.Assert(err, check.IsNil) if i%3 == 0 { @@ -221,7 +221,7 @@ func (t *testShardMetaSuite) TestShardingMetaWrongSequence(c *check.C) { c.Assert(meta.ResolveShardingDDL(), check.IsFalse) // 2nd round sharding DDL sync - for i := 0; i < 4; i++ { + for i := range 4 { if i%3 == 0 { continue } diff --git a/dm/syncer/sharding_group.go b/dm/syncer/sharding_group.go index 9151fca609..d1e3d794ad 100644 --- a/dm/syncer/sharding_group.go +++ b/dm/syncer/sharding_group.go @@ -72,6 +72,7 @@ package syncer import ( "fmt" + "maps" "sync" "github.com/pingcap/tidb/pkg/util/dbutil" @@ -279,9 +280,7 @@ func (sg *ShardingGroup) Sources() map[string]bool { sg.RLock() defer sg.RUnlock() ret := make(map[string]bool, len(sg.sources)) - for k, v := range sg.sources { - ret[k] = v - } + maps.Copy(ret, sg.sources) return ret } @@ -366,7 +365,7 @@ func (sg *ShardingGroup) ActiveDDLFirstLocation() (binlog.Location, error) { } // FlushData returns sharding meta flush SQLs and args. -func (sg *ShardingGroup) FlushData(targetTableID string) ([]string, [][]interface{}) { +func (sg *ShardingGroup) FlushData(targetTableID string) ([]string, [][]any) { sg.RLock() defer sg.RUnlock() return sg.meta.FlushData(sg.sourceID, targetTableID) @@ -619,9 +618,7 @@ func (k *ShardingGroupKeeper) Groups() map[string]*ShardingGroup { // do a copy groups := make(map[string]*ShardingGroup, len(k.groups)) - for key, value := range k.groups { - groups[key] = value - } + maps.Copy(groups, k.groups) return groups } @@ -662,12 +659,12 @@ func (k *ShardingGroupKeeper) ActiveDDLFirstLocation(targetTable *filter.Table) } // PrepareFlushSQLs returns all sharding meta flushed SQLs except for given table IDs. -func (k *ShardingGroupKeeper) PrepareFlushSQLs(exceptTableIDs map[string]bool) ([]string, [][]interface{}) { +func (k *ShardingGroupKeeper) PrepareFlushSQLs(exceptTableIDs map[string]bool) ([]string, [][]any) { k.RLock() defer k.RUnlock() var ( sqls = make([]string, 0, len(k.groups)) - args = make([][]interface{}, 0, len(k.groups)) + args = make([][]any, 0, len(k.groups)) ) for id, group := range k.groups { if group.IsSchemaOnly { diff --git a/dm/syncer/status.go b/dm/syncer/status.go index e2687ab7e4..02729372ca 100644 --- a/dm/syncer/status.go +++ b/dm/syncer/status.go @@ -27,7 +27,7 @@ import ( ) // Status implements Unit.Status. -func (s *Syncer) Status(sourceStatus *binlog.SourceStatus) interface{} { +func (s *Syncer) Status(sourceStatus *binlog.SourceStatus) any { syncerLocation := s.checkpoint.FlushedGlobalPoint() st := &pb.SyncStatus{ TotalEvents: s.count.Load(), diff --git a/dm/syncer/status_test.go b/dm/syncer/status_test.go index c346654be3..b0553e8821 100644 --- a/dm/syncer/status_test.go +++ b/dm/syncer/status_test.go @@ -56,15 +56,13 @@ func (t *statusSuite) TestStatusRace(c *check.C) { } wg := sync.WaitGroup{} - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 10 { + wg.Go(func() { ret := s.Status(sourceStatus) status := ret.(*pb.SyncStatus) c.Assert(status.MasterBinlog, check.Equals, "(mysql-bin.000123, 223)") c.Assert(status.SyncerBinlog, check.Equals, "(mysql-bin.000123, 123)") - }() + }) } wg.Wait() } diff --git a/dm/syncer/syncer.go b/dm/syncer/syncer.go index 1013bf2a39..f35d6f2ab3 100644 --- a/dm/syncer/syncer.go +++ b/dm/syncer/syncer.go @@ -361,7 +361,7 @@ func (s *Syncer) closeJobChans() { s.jobsClosed.Store(true) } -func (s *Syncer) recordUnhandledEvent(message string, ev interface{}) { +func (s *Syncer) recordUnhandledEvent(message string, ev any) { s.unhandledEventLogger.Warn(message, zap.String("type", fmt.Sprintf("%T", ev))) } @@ -758,9 +758,7 @@ func (s *Syncer) Process(ctx context.Context, pr chan pb.ProcessResult) { ) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { err, ok := <-runFatalChan if !ok { @@ -771,13 +769,11 @@ func (s *Syncer) Process(ctx context.Context, pr chan pb.ProcessResult) { errs = append(errs, err) errsMu.Unlock() } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { <-newCtx.Done() // ctx or newCtx - }() + }) err := s.Run(newCtx) if err != nil { @@ -1362,7 +1358,7 @@ func (s *Syncer) flushCheckPointsAsync(asyncFlushJob *job) { s.checkpointFlushWorker.Add(task) } -func (s *Syncer) createCheckpointSnapshot(isSyncFlush bool) (*SnapshotInfo, []*filter.Table, []string, [][]interface{}) { +func (s *Syncer) createCheckpointSnapshot(isSyncFlush bool) (*SnapshotInfo, []*filter.Table, []string, [][]any) { snapshotInfo := s.checkpoint.Snapshot(isSyncFlush) if snapshotInfo == nil { return nil, nil, nil, nil @@ -1372,7 +1368,7 @@ func (s *Syncer) createCheckpointSnapshot(isSyncFlush bool) (*SnapshotInfo, []*f exceptTableIDs map[string]bool exceptTables []*filter.Table shardMetaSQLs []string - shardMetaArgs [][]interface{} + shardMetaArgs [][]any ) if s.cfg.ShardMode == config.ShardPessimistic { // flush all checkpoints except tables which are unresolved for sharding DDL for the pessimistic mode. @@ -1836,12 +1832,10 @@ func (s *Syncer) Run(ctx context.Context) (err error) { s.runWg.Add(1) go s.syncDML() - s.runWg.Add(1) - go func() { - defer s.runWg.Done() + s.runWg.Go(func() { // also need to use a different ctx. checkpointFlushWorker worker will be closed in the first defer s.checkpointFlushWorker.Run(s.tctx) - }() + }) s.runWg.Add(1) go s.syncDDL(adminQueueName, s.ddlDBConn, s.ddlJobCh) s.runWg.Add(1) @@ -2805,13 +2799,13 @@ func (qec *queryEventContext) String() string { } // generateExtendColumn generate extended columns by extractor. -func generateExtendColumn(data [][]interface{}, r *regexprrouter.RouteTable, table *filter.Table, sourceID string) [][]interface{} { +func generateExtendColumn(data [][]any, r *regexprrouter.RouteTable, table *filter.Table, sourceID string) [][]any { extendCol, extendVal := r.FetchExtendColumn(table.Schema, table.Name, sourceID) if len(extendCol) == 0 { return nil } - rows := make([][]interface{}, len(data)) + rows := make([][]any, len(data)) for i := range data { rows[i] = data[i] for _, v := range extendVal { @@ -2913,10 +2907,7 @@ func (s *Syncer) trackDDL(usedSchema string, trackInfo *ddlInfo, ec *eventContex } } // skip getTable before in above loop - start := 1 - if shouldTableExistNum > start { - start = shouldTableExistNum - } + start := max(shouldTableExistNum, 1) for i := start; i < shouldRefTableExistNum; i++ { if err := s.schemaTracker.CreateSchemaIfNotExists(srcTables[i].Schema); err != nil { return terror.ErrSchemaTrackerCannotCreateSchema.Delegate(err, srcTables[i].Schema) @@ -3100,8 +3091,8 @@ func (s *Syncer) loadTableStructureFromDump(ctx context.Context) error { setFirstErr(err2) continue } - stmts := bytes.Split(content, []byte(";\n")) - for _, stmt := range stmts { + stmts := bytes.SplitSeq(content, []byte(";\n")) + for stmt := range stmts { stmt = bytes.TrimSpace(stmt) if len(stmt) == 0 || bytes.HasPrefix(stmt, []byte("/*")) { continue diff --git a/dm/syncer/syncer_test.go b/dm/syncer/syncer_test.go index 1366cd9bc2..7864769c35 100644 --- a/dm/syncer/syncer_test.go +++ b/dm/syncer/syncer_test.go @@ -76,7 +76,7 @@ type ( mockBinlogEvents []mockBinlogEvent mockBinlogEvent struct { typ int - args []interface{} + args []any } ) @@ -180,7 +180,7 @@ func (s *testSyncerSuite) generateEvents(binlogEvents mockBinlogEvents, c *check Schema: e.args[1].(string), Table: e.args[2].(string), ColumnType: e.args[3].([]byte), - Rows: e.args[4].([][]interface{}), + Rows: e.args[4].([][]any), }, } var eventType replication.EventType @@ -237,7 +237,7 @@ func (s *testSyncerSuite) TestSampleUnhandledEvents(c *check.C) { entries := logs.All() c.Assert(entries, check.HasLen, 2) - seen := make(map[string][]map[string]interface{}, len(entries)) + seen := make(map[string][]map[string]any, len(entries)) for _, entry := range entries { seen[entry.Message] = append(seen[entry.Message], entry.ContextMap()) } @@ -337,33 +337,33 @@ func (s *testSyncerSuite) TestSelectTable(c *check.C) { } s.resetEventsGenerator(c) events := mockBinlogEvents{ - mockBinlogEvent{typ: DBCreate, args: []interface{}{"s1"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"s1", "create table s1.log(id int)"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"s1"}}, - - mockBinlogEvent{typ: TableCreate, args: []interface{}{"mysql", "create table mysql.test(id int)"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"mysql", "test"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"stest"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest", "create table stest.log(id int)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest", "create table stest.t(id int)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest", "create table stest.log2(id int)"}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "stest", "t", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(9), "stest", "log", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(10), "stest", "log2", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest", "log"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest", "t"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest", "log2"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"stest"}}, - - mockBinlogEvent{typ: DBCreate, args: []interface{}{"t2"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"t2", "create table t2.log(id int)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"t2", "create table t2.log1(id int)"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"t2", "log"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"t2"}}, - - mockBinlogEvent{typ: DBCreate, args: []interface{}{"ptest1"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"ptest1", "create table ptest1.t1(id int)"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"ptest1"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"s1"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"s1", "create table s1.log(id int)"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"s1"}}, + + mockBinlogEvent{typ: TableCreate, args: []any{"mysql", "create table mysql.test(id int)"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"mysql", "test"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"stest"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest", "create table stest.log(id int)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest", "create table stest.t(id int)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest", "create table stest.log2(id int)"}}, + mockBinlogEvent{typ: Write, args: []any{uint64(8), "stest", "t", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(9), "stest", "log", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(10), "stest", "log2", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest", "log"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest", "t"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest", "log2"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"stest"}}, + + mockBinlogEvent{typ: DBCreate, args: []any{"t2"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"t2", "create table t2.log(id int)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"t2", "create table t2.log1(id int)"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"t2", "log"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"t2"}}, + + mockBinlogEvent{typ: DBCreate, args: []any{"ptest1"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"ptest1", "create table ptest1.t1(id int)"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"ptest1"}}, } allEvents := s.generateEvents(events, c) @@ -417,18 +417,18 @@ func (s *testSyncerSuite) TestIgnoreDB(c *check.C) { s.resetEventsGenerator(c) events := mockBinlogEvents{ - mockBinlogEvent{typ: DBCreate, args: []interface{}{"s1"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"s1"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"s2"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"s2"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"btest"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"btest"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"b1"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"b1"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"stest"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"stest"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"st"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"st"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"s1"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"s1"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"s2"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"s2"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"btest"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"btest"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"b1"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"b1"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"stest"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"stest"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"st"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"st"}}, } allEvents := s.generateEvents(events, c) @@ -480,31 +480,31 @@ func (s *testSyncerSuite) TestIgnoreTable(c *check.C) { s.resetEventsGenerator(c) events := mockBinlogEvents{ - mockBinlogEvent{typ: DBCreate, args: []interface{}{"s1"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"s1", "create table s1.log(id int)"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"s1"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"mysql", "create table mysql.test(id int)"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"mysql", "test"}}, - - mockBinlogEvent{typ: DBCreate, args: []interface{}{"stest"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest", "create table stest.log(id int)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest", "create table stest.t(id int)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest", "create table stest.log2(id int)"}}, - - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "stest", "t", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(9), "stest", "log", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(10), "stest", "log2", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}, + mockBinlogEvent{typ: DBCreate, args: []any{"s1"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"s1", "create table s1.log(id int)"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"s1"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"mysql", "create table mysql.test(id int)"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"mysql", "test"}}, + + mockBinlogEvent{typ: DBCreate, args: []any{"stest"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest", "create table stest.log(id int)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest", "create table stest.t(id int)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest", "create table stest.log2(id int)"}}, + + mockBinlogEvent{typ: Write, args: []any{uint64(8), "stest", "t", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(9), "stest", "log", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(10), "stest", "log2", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}, // TODO event generator support generate an event with multiple tables DDL - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest", "log"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest", "t"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest", "log2"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"stest"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest", "log"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest", "t"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest", "log2"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"stest"}}, - mockBinlogEvent{typ: DBCreate, args: []interface{}{"t2"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"t2", "create table t2.log(id int)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"t2", "create table t2.log1(id int)"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"t2", "log"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"t2"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"t2"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"t2", "create table t2.log(id int)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"t2", "create table t2.log1(id int)"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"t2", "log"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"t2"}}, } allEvents := s.generateEvents(events, c) @@ -584,49 +584,49 @@ func (s *testSyncerSuite) TestSkipDML(c *check.C) { sqls := make([]SQLChecker, 0, 16) - evs := s.generateEvents([]mockBinlogEvent{{DBCreate, []interface{}{"foo"}}}, c) + evs := s.generateEvents([]mockBinlogEvent{{DBCreate, []any{"foo"}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: false, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{TableCreate, []interface{}{"foo", "create table foo.bar(id int)"}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{TableCreate, []any{"foo", "create table foo.bar(id int)"}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: false, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{Write, []interface{}{uint64(8), "foo", "bar", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(1)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Write, []any{uint64(8), "foo", "bar", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(1)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{Update, []interface{}{uint64(8), "foo", "bar", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(2)}, {int32(1)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Update, []any{uint64(8), "foo", "bar", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(2)}, {int32(1)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: true}) - evs = s.generateEvents([]mockBinlogEvent{{Delete, []interface{}{uint64(8), "foo", "bar", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(2)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Delete, []any{uint64(8), "foo", "bar", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(2)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: true}) - evs = s.generateEvents([]mockBinlogEvent{{DBDrop, []interface{}{"foo1"}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{DBDrop, []any{"foo1"}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: false, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{DBCreate, []interface{}{"foo1"}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{DBCreate, []any{"foo1"}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: false, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{TableCreate, []interface{}{"foo1", "create table foo1.bar1(id int)"}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{TableCreate, []any{"foo1", "create table foo1.bar1(id int)"}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: false, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{Write, []interface{}{uint64(9), "foo1", "bar1", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(1)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Write, []any{uint64(9), "foo1", "bar1", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(1)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{Update, []interface{}{uint64(9), "foo1", "bar1", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(2)}, {int32(1)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Update, []any{uint64(9), "foo1", "bar1", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(2)}, {int32(1)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: true}) - evs = s.generateEvents([]mockBinlogEvent{{Delete, []interface{}{uint64(9), "foo1", "bar1", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(2)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Delete, []any{uint64(9), "foo1", "bar1", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(2)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: true}) - evs = s.generateEvents([]mockBinlogEvent{{TableCreate, []interface{}{"foo1", "create table foo1.bar2(id int)"}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{TableCreate, []any{"foo1", "create table foo1.bar2(id int)"}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: false, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{Write, []interface{}{uint64(10), "foo1", "bar2", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(1)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Write, []any{uint64(10), "foo1", "bar2", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(1)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: false}) - evs = s.generateEvents([]mockBinlogEvent{{Update, []interface{}{uint64(10), "foo1", "bar2", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(2)}, {int32(1)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Update, []any{uint64(10), "foo1", "bar2", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(2)}, {int32(1)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: true}) - evs = s.generateEvents([]mockBinlogEvent{{Delete, []interface{}{uint64(10), "foo1", "bar2", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(2)}}}}}, c) + evs = s.generateEvents([]mockBinlogEvent{{Delete, []any{uint64(10), "foo1", "bar2", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(2)}}}}}, c) sqls = append(sqls, SQLChecker{events: evs, isDML: true, expected: true}) p := parser.New() @@ -684,10 +684,10 @@ func (s *testSyncerSuite) TestColumnMapping(c *check.C) { // create db and tables events := mockBinlogEvents{ - mockBinlogEvent{typ: DBCreate, args: []interface{}{"stest_3"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest_3", "create table stest_3.log(id varchar(45))"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest_3", "create table stest_3.t_2(name varchar(45), id bigint)"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest_3", "create table stest_3.a(id int)"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"stest_3"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest_3", "create table stest_3.log(id varchar(45))"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest_3", "create table stest_3.t_2(name varchar(45), id bigint)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"stest_3", "create table stest_3.a(id int)"}}, } createEvents := s.generateEvents(events, c) @@ -696,19 +696,19 @@ func (s *testSyncerSuite) TestColumnMapping(c *check.C) { type dml struct { events []*replication.BinlogEvent column []string - data []interface{} + data []any } dmls := make([]dml, 0, 3) - evs := s.generateEvents([]mockBinlogEvent{{typ: Write, args: []interface{}{uint64(8), "stest_3", "t_2", []byte{mysql.MYSQL_TYPE_STRING, mysql.MYSQL_TYPE_LONG}, [][]interface{}{{"ian", int32(10)}}}}}, c) - dmls = append(dmls, dml{events: evs, column: []string{"name", "id"}, data: []interface{}{"ian", int64(1<<59 | 3<<52 | 2<<44 | 10)}}) + evs := s.generateEvents([]mockBinlogEvent{{typ: Write, args: []any{uint64(8), "stest_3", "t_2", []byte{mysql.MYSQL_TYPE_STRING, mysql.MYSQL_TYPE_LONG}, [][]any{{"ian", int32(10)}}}}}, c) + dmls = append(dmls, dml{events: evs, column: []string{"name", "id"}, data: []any{"ian", int64(1<<59 | 3<<52 | 2<<44 | 10)}}) - evs = s.generateEvents([]mockBinlogEvent{{typ: Write, args: []interface{}{uint64(9), "stest_3", "log", []byte{mysql.MYSQL_TYPE_STRING}, [][]interface{}{{"10"}}}}}, c) - dmls = append(dmls, dml{events: evs, column: []string{"id"}, data: []interface{}{"test:10"}}) + evs = s.generateEvents([]mockBinlogEvent{{typ: Write, args: []any{uint64(9), "stest_3", "log", []byte{mysql.MYSQL_TYPE_STRING}, [][]any{{"10"}}}}}, c) + dmls = append(dmls, dml{events: evs, column: []string{"id"}, data: []any{"test:10"}}) - evs = s.generateEvents([]mockBinlogEvent{{typ: Write, args: []interface{}{uint64(10), "stest_3", "a", []byte{mysql.MYSQL_TYPE_LONG}, [][]interface{}{{int32(10)}}}}}, c) - dmls = append(dmls, dml{events: evs, column: []string{"id"}, data: []interface{}{int32(10)}}) + evs = s.generateEvents([]mockBinlogEvent{{typ: Write, args: []any{uint64(10), "stest_3", "a", []byte{mysql.MYSQL_TYPE_LONG}, [][]any{{int32(10)}}}}}, c) + dmls = append(dmls, dml{events: evs, column: []string{"id"}, data: []any{int32(10)}}) dmlEvents := make([]*replication.BinlogEvent, 0, 15) for _, dml := range dmls { @@ -718,10 +718,10 @@ func (s *testSyncerSuite) TestColumnMapping(c *check.C) { // drop tables and db events = mockBinlogEvents{ // TODO event generator support generate an event with multiple tables DDL - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest_3", "log"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest_3", "t_2"}}, - mockBinlogEvent{typ: TableDrop, args: []interface{}{"stest_3", "a"}}, - mockBinlogEvent{typ: DBDrop, args: []interface{}{"stest_3"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest_3", "log"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest_3", "t_2"}}, + mockBinlogEvent{typ: TableDrop, args: []any{"stest_3", "a"}}, + mockBinlogEvent{typ: DBDrop, args: []any{"stest_3"}}, } dropEvents := s.generateEvents(events, c) @@ -832,19 +832,19 @@ func (s *testSyncerSuite) TestRun(c *check.C) { syncer.reset() events1 := mockBinlogEvents{ - mockBinlogEvent{typ: DBCreate, args: []interface{}{"test_1"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"test_1", "create table test_1.t_1(id int primary key, name varchar(24))"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"test_1", "create table test_1.t_2(id int primary key, name varchar(24))"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"test_1"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"test_1", "create table test_1.t_1(id int primary key, name varchar(24))"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"test_1", "create table test_1.t_2(id int primary key, name varchar(24))"}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(1), "a"}}}}, - mockBinlogEvent{typ: DDL, args: []interface{}{"test_1", "alter table test_1.t_1 add index index1(name)"}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(2), "b"}}}}, - mockBinlogEvent{typ: Delete, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(1), "a"}}}}, - mockBinlogEvent{typ: Update, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(2), "b"}, {int32(1), "b"}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(1), "a"}}}}, + mockBinlogEvent{typ: DDL, args: []any{"test_1", "alter table test_1.t_1 add index index1(name)"}}, + mockBinlogEvent{typ: Write, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(2), "b"}}}}, + mockBinlogEvent{typ: Delete, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(1), "a"}}}}, + mockBinlogEvent{typ: Update, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(2), "b"}, {int32(1), "b"}}}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"test_1", "create table test_1.t_3(id int primary key, name varchar(24))"}}, - mockBinlogEvent{typ: DDL, args: []interface{}{"test_1", "alter table test_1.t_3 drop primary key"}}, - mockBinlogEvent{typ: DDL, args: []interface{}{"test_1", "alter table test_1.t_3 add primary key(id, name)"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"test_1", "create table test_1.t_3(id int primary key, name varchar(24))"}}, + mockBinlogEvent{typ: DDL, args: []any{"test_1", "alter table test_1.t_3 drop primary key"}}, + mockBinlogEvent{typ: DDL, args: []any{"test_1", "alter table test_1.t_3 add primary key(id, name)"}}, } mockStreamerProducer := &MockStreamProducer{s.generateEvents(events1, c)} @@ -899,7 +899,7 @@ func (s *testSyncerSuite) TestRun(c *check.C) { }, { dml, []string{"REPLACE INTO `test_1`.`t_1` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(1), "a"}}, + [][]any{{int64(1), "a"}}, }, { flush, nil, @@ -911,16 +911,16 @@ func (s *testSyncerSuite) TestRun(c *check.C) { }, { dml, []string{"REPLACE INTO `test_1`.`t_1` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(2), "b"}}, + [][]any{{int64(2), "b"}}, }, { dml, []string{"DELETE FROM `test_1`.`t_1` WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{int64(1)}}, + [][]any{{int64(1)}}, }, { // safe mode is true, will split update to delete + replace dml, []string{"DELETE FROM `test_1`.`t_1` WHERE `id` = ? LIMIT 1", "REPLACE INTO `test_1`.`t_1` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(2)}, {int64(1), "b"}}, + [][]any{{int64(2)}, {int64(1), "b"}}, }, { flush, nil, @@ -991,8 +991,8 @@ func (s *testSyncerSuite) TestRun(c *check.C) { c.Assert(syncer.timezone.String(), check.Equals, "+01:00") events2 := mockBinlogEvents{ - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(3), "c"}}}}, - mockBinlogEvent{typ: Delete, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(3), "c"}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(3), "c"}}}}, + mockBinlogEvent{typ: Delete, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(3), "c"}}}}, } ctx, cancel = context.WithCancel(context.Background()) @@ -1029,11 +1029,11 @@ func (s *testSyncerSuite) TestRun(c *check.C) { { dml, []string{"INSERT INTO `test_1`.`t_2` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(3), "c"}}, + [][]any{{int64(3), "c"}}, }, { dml, []string{"DELETE FROM `test_1`.`t_2` WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{int64(3)}}, + [][]any{{int64(3)}}, }, { flush, nil, @@ -1165,12 +1165,12 @@ func (s *testSyncerSuite) TestExitSafeModeByConfig(c *check.C) { syncer.reset() events1 := mockBinlogEvents{ - mockBinlogEvent{typ: DBCreate, args: []interface{}{"test_1"}}, - mockBinlogEvent{typ: TableCreate, args: []interface{}{"test_1", "create table test_1.t_1(id int primary key, name varchar(24))"}}, + mockBinlogEvent{typ: DBCreate, args: []any{"test_1"}}, + mockBinlogEvent{typ: TableCreate, args: []any{"test_1", "create table test_1.t_1(id int primary key, name varchar(24))"}}, - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(1), "a"}}}}, - mockBinlogEvent{typ: Delete, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(1), "a"}}}}, - mockBinlogEvent{typ: Update, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(2), "b"}, {int32(1), "b"}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(1), "a"}}}}, + mockBinlogEvent{typ: Delete, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(1), "a"}}}}, + mockBinlogEvent{typ: Update, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(2), "b"}, {int32(1), "b"}}}}, } generatedEvents1 := s.generateEvents(events1, c) @@ -1182,9 +1182,9 @@ func (s *testSyncerSuite) TestExitSafeModeByConfig(c *check.C) { // check after safeModeExitLocation, safe mode is turned off events2 := mockBinlogEvents{ - mockBinlogEvent{typ: Write, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(1), "a"}}}}, - mockBinlogEvent{typ: Delete, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(1), "a"}}}}, - mockBinlogEvent{typ: Update, args: []interface{}{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]interface{}{{int32(2), "b"}, {int32(1), "b"}}}}, + mockBinlogEvent{typ: Write, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(1), "a"}}}}, + mockBinlogEvent{typ: Delete, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(1), "a"}}}}, + mockBinlogEvent{typ: Update, args: []any{uint64(8), "test_1", "t_1", []byte{mysql.MYSQL_TYPE_LONG, mysql.MYSQL_TYPE_STRING}, [][]any{{int32(2), "b"}, {int32(1), "b"}}}}, } generatedEvents2 := s.generateEvents(events2, c) @@ -1248,28 +1248,28 @@ func (s *testSyncerSuite) TestExitSafeModeByConfig(c *check.C) { }, { dml, []string{"REPLACE INTO `test_1`.`t_1` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(1), "a"}}, + [][]any{{int64(1), "a"}}, }, { dml, []string{"DELETE FROM `test_1`.`t_1` WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{int64(1)}}, + [][]any{{int64(1)}}, }, { dml, []string{"DELETE FROM `test_1`.`t_1` WHERE `id` = ? LIMIT 1", "REPLACE INTO `test_1`.`t_1` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(2)}, {int64(1), "b"}}, + [][]any{{int64(2)}, {int64(1), "b"}}, }, { // start from this event, location passes safeModeExitLocation and safe mode should exit dml, []string{"INSERT INTO `test_1`.`t_1` (`id`,`name`) VALUES (?,?)"}, - [][]interface{}{{int64(1), "a"}}, + [][]any{{int64(1), "a"}}, }, { dml, []string{"DELETE FROM `test_1`.`t_1` WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{int64(1)}}, + [][]any{{int64(1)}}, }, { dml, []string{"UPDATE `test_1`.`t_1` SET `id` = ?, `name` = ? WHERE `id` = ? LIMIT 1"}, - [][]interface{}{{int64(1), "b", int64(2)}}, + [][]any{{int64(1), "b", int64(2)}}, }, { flush, nil, @@ -1515,7 +1515,7 @@ func checkEventWithTableResult(c *check.C, syncer *Syncer, allEvents []*replicat } func executeSQLAndWait(expectJobNum int) { - for i := 0; i < 10; i++ { + for range 10 { time.Sleep(time.Second) testJobs.RLock() @@ -1531,7 +1531,7 @@ func executeSQLAndWait(expectJobNum int) { type expectJob struct { tp opType sqlInJob []string - args [][]interface{} + args [][]any } var defaultDMLType = map[sqlmodel.RowChangeType]sqlmodel.DMLType{ @@ -1554,7 +1554,7 @@ func checkJobs(c *check.C, jobs []*job, expectJobs []*expectJob) { if !job.safeMode { sql, args := job.dml.GenSQL(defaultDMLType[job.dml.Type()]) c.Assert([]string{sql}, check.DeepEquals, expectJobs[i].sqlInJob) - c.Assert([][]interface{}{args}, check.DeepEquals, expectJobs[i].args) + c.Assert([][]any{args}, check.DeepEquals, expectJobs[i].args) continue } @@ -1563,16 +1563,16 @@ func checkJobs(c *check.C, jobs []*job, expectJobs []*expectJob) { case sqlmodel.RowChangeInsert: sql, args := job.dml.GenSQL(sqlmodel.DMLReplace) c.Assert([]string{sql}, check.DeepEquals, expectJobs[i].sqlInJob) - c.Assert([][]interface{}{args}, check.DeepEquals, expectJobs[i].args) + c.Assert([][]any{args}, check.DeepEquals, expectJobs[i].args) case sqlmodel.RowChangeUpdate: sql, args := job.dml.GenSQL(sqlmodel.DMLDelete) sql2, args2 := job.dml.GenSQL(sqlmodel.DMLReplace) c.Assert([]string{sql, sql2}, check.DeepEquals, expectJobs[i].sqlInJob) - c.Assert([][]interface{}{args, args2}, check.DeepEquals, expectJobs[i].args) + c.Assert([][]any{args, args2}, check.DeepEquals, expectJobs[i].args) case sqlmodel.RowChangeDelete: sql, args := job.dml.GenSQL(sqlmodel.DMLDelete) c.Assert([]string{sql}, check.DeepEquals, expectJobs[i].sqlInJob) - c.Assert([][]interface{}{args}, check.DeepEquals, expectJobs[i].args) + c.Assert([][]any{args}, check.DeepEquals, expectJobs[i].args) } } } @@ -1934,11 +1934,9 @@ func TestWaitBeforeRunExit(t *testing.T) { wg := &sync.WaitGroup{} errCh := make(chan error, 1) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { errCh <- syncer.Run(ctx) - }() + }) time.Sleep(time.Second) // wait s.Run start // test s.Run will not exit unit caller cancel ctx or call s.runCancel diff --git a/dm/syncer/validate_worker.go b/dm/syncer/validate_worker.go index 3e7082085f..8a2ccd0e10 100644 --- a/dm/syncer/validate_worker.go +++ b/dm/syncer/validate_worker.go @@ -17,6 +17,7 @@ import ( "context" "database/sql" "fmt" + "maps" "math" "strconv" "strings" @@ -201,9 +202,7 @@ func (vw *validateWorker) validateTableChange() { if err2 != nil { return err2 } - for key, val := range failedRows { - allFailedRows[key] = val - } + maps.Copy(allFailedRows, failedRows) return nil } if err = validateFunc(insertUpdateChanges, false); err != nil { @@ -282,18 +281,13 @@ func (vw *validateWorker) updatePendingAndErrorRows(failedChanges map[string]map func (vw *validateWorker) validateRowChanges(rows []*rowValidationJob, deleteChange bool) (map[string]*validateFailedRow, error) { res := make(map[string]*validateFailedRow) for start := 0; start < len(rows); start += vw.batchSize { - end := start + vw.batchSize - if end > len(rows) { - end = len(rows) - } + end := min(start+vw.batchSize, len(rows)) batch := rows[start:end] failedRows, err := vw.batchValidateRowChanges(batch, deleteChange) if err != nil { return nil, err } - for k, v := range failedRows { - res[k] = v - } + maps.Copy(res, failedRows) } return res, nil } @@ -528,7 +522,7 @@ func scanRow(rows *sql.Rows) ([]*sql.NullString, error) { } colVals := make([][]byte, len(cols)) - colValsI := make([]interface{}, len(colVals)) + colValsI := make([]any, len(colVals)) for i := range colValsI { colValsI[i] = &colVals[i] } diff --git a/dm/syncer/validate_worker_test.go b/dm/syncer/validate_worker_test.go index 34161d0409..da750b9405 100644 --- a/dm/syncer/validate_worker_test.go +++ b/dm/syncer/validate_worker_test.go @@ -36,8 +36,8 @@ import ( "github.com/stretchr/testify/require" ) -func genRowChangeJob(tbl filter.Table, tblInfo *model.TableInfo, key string, tp rowChangeJobType, data []interface{}) *rowValidationJob { - var beforeImage, afterImage []interface{} +func genRowChangeJob(tbl filter.Table, tblInfo *model.TableInfo, key string, tp rowChangeJobType, data []any) *rowValidationJob { + var beforeImage, afterImage []any switch tp { case rowInsert: afterImage = data @@ -104,9 +104,9 @@ func TestValidatorWorkerValidateTableChanges(t *testing.T) { checkInitStatus() // insert & update same table, both row are validated failed - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []interface{}{1, "a"})) - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowUpdated, []interface{}{1, "b"})) - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "2", rowInsert, []interface{}{2, "2b"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []any{1, "a"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowUpdated, []any{1, "b"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "2", rowInsert, []any{2, "2b"})) mock.ExpectQuery("SELECT .* FROM .*tbl1.* WHERE .*").WillReturnRows( sqlmock.NewRows([]string{"a", "b"}).AddRow(2, "incorrect data")) @@ -163,8 +163,8 @@ func TestValidatorWorkerValidateTableChanges(t *testing.T) { // // add 2 delete row of tbl2 and tbl3 - worker.updateRowChange(genRowChangeJob(tbl2, tableInfo2, "a", rowDeleted, []interface{}{"a", "b"})) - worker.updateRowChange(genRowChangeJob(tbl3, tableInfo3, "aa", rowDeleted, []interface{}{"aa", "b"})) + worker.updateRowChange(genRowChangeJob(tbl2, tableInfo2, "a", rowDeleted, []any{"a", "b"})) + worker.updateRowChange(genRowChangeJob(tbl3, tableInfo3, "aa", rowDeleted, []any{"aa", "b"})) mock.ExpectQuery("SELECT .* FROM .*tbl1.* WHERE .*").WillReturnRows( sqlmock.NewRows([]string{"a", "b"})) @@ -208,9 +208,9 @@ func TestValidatorWorkerValidateTableChanges(t *testing.T) { // // validate with batch size = 2 worker.batchSize = 2 - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []interface{}{1, "a"})) - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "2", rowInsert, []interface{}{2, "2b"})) - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "3", rowInsert, []interface{}{3, "3c"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []any{1, "a"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "2", rowInsert, []any{2, "2b"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "3", rowInsert, []any{3, "3c"})) mock.ExpectQuery("SELECT .* FROM .*tbl1.* WHERE .*").WillReturnRows( sqlmock.NewRows([]string{"a", "b"}).AddRow(1, "a").AddRow(2, "2b")) @@ -273,7 +273,7 @@ func TestValidatorWorkerValidateTableChanges(t *testing.T) { // set markErrorStarted = false, there should not be any errors and failedCount=0 validator.markErrorStarted.Store(false) - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []interface{}{1, "a"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []any{1, "a"})) mock.ExpectQuery("SELECT .* FROM .*tbl1.* WHERE .*").WillReturnRows( sqlmock.NewRows([]string{"a", "b"})) @@ -304,7 +304,7 @@ func TestValidatorWorkerValidateTableChanges(t *testing.T) { // set markErrorStarted=true, rowErrorDelayInSec = 0, failed rows became error directly validator.markErrorStarted.Store(true) worker.rowErrorDelayInSec = 0 - worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []interface{}{1, "a"})) + worker.updateRowChange(genRowChangeJob(tbl1, tableInfo1, "1", rowInsert, []any{1, "a"})) mock.ExpectQuery("SELECT .* FROM .*tbl1.* WHERE .*").WillReturnRows( sqlmock.NewRows([]string{"a", "b"})) worker.validateTableChange() @@ -396,7 +396,7 @@ func TestValidatorWorkerGetTargetRows(t *testing.T) { creatSQL string pkValues [][]string allCols []string - rowData [][]interface{} + rowData [][]any querySQL string } testCases := []testCase{ @@ -413,7 +413,7 @@ func TestValidatorWorkerGetTargetRows(t *testing.T) { {"1", "2"}, {"3", "4"}, {"5", "6"}, }, allCols: []string{"a", "b", "c"}, - rowData: [][]interface{}{ + rowData: [][]any{ {"1", "2", "3"}, {"3", "4", "5"}, {"5", "6", "7"}, }, querySQL: "SELECT .* FROM .*test1.*", @@ -432,7 +432,7 @@ func TestValidatorWorkerGetTargetRows(t *testing.T) { {"a"}, {"b"}, {"c"}, }, allCols: []string{"a", "other", "b", "c"}, - rowData: [][]interface{}{ + rowData: [][]any{ {"a", "aaa", "\xdd\xcc", "1"}, {"b", "bbb", nil, "2"}, {"c", nil, nil, "3"}, }, querySQL: "SELECT .* FROM .*test2.*", @@ -513,8 +513,8 @@ func TestValidatorWorkerGetSourceRowsForCompare(t *testing.T) { tbl1 := filter.Table{Schema: "test", Name: "tbl1"} tableInfo1 := genValidateTableInfo(t, "create table tbl1(a varchar(10) primary key, b int)") rows := getSourceRowsForCompare([]*rowValidationJob{ - genRowChangeJob(tbl1, tableInfo1, "a", rowInsert, []interface{}{nil, 1}), - genRowChangeJob(tbl1, tableInfo1, "b", rowInsert, []interface{}{1, 2}), + genRowChangeJob(tbl1, tableInfo1, "a", rowInsert, []any{nil, 1}), + genRowChangeJob(tbl1, tableInfo1, "b", rowInsert, []any{1, 2}), }) require.Len(t, rows, 2) require.Len(t, rows["a"], 2) diff --git a/dm/syncer/validator_checkpoint.go b/dm/syncer/validator_checkpoint.go index bc1ab1e211..8e788038a4 100644 --- a/dm/syncer/validator_checkpoint.go +++ b/dm/syncer/validator_checkpoint.go @@ -99,7 +99,7 @@ func (c *validatorPersistHelper) init(tctx *tcontext.Context) error { c.db = c.validator.toDB if !c.schemaInitialized.Load() { - workFunc := func(tctx *tcontext.Context) (interface{}, error) { + workFunc := func(tctx *tcontext.Context) (any, error) { return nil, c.createSchemaAndTables(tctx) } if _, cnt, err := c.retryer.Apply(tctx, workFunc); err != nil { @@ -207,14 +207,14 @@ type rowChangeDataForPersist struct { Key string `json:"key"` Tp rowChangeJobType `json:"tp"` Size int32 `json:"size"` - Data []interface{} `json:"data"` + Data []any `json:"data"` FailedCnt int `json:"failed-cnt"` // failed count } var triggeredFailOnPersistForIntegrationTest bool -func (c *validatorPersistHelper) execQueriesWithRetry(tctx *tcontext.Context, queries []string, args [][]interface{}) error { - workFunc := func(tctx *tcontext.Context) (interface{}, error) { +func (c *validatorPersistHelper) execQueriesWithRetry(tctx *tcontext.Context, queries []string, args [][]any) error { + workFunc := func(tctx *tcontext.Context) (any, error) { for i, q := range queries { failpoint.Inject("ValidatorFailOnPersist", func() { // on persist pending row changes, the queries would be [delete, insert...] @@ -246,7 +246,7 @@ func (c *validatorPersistHelper) persistTableStatusAndErrors(tctx *tcontext.Cont tableStatus := c.validator.getTableStatusMap() count := len(tableStatus) + int(c.validator.getNewErrorRowCount()) queries := make([]string, 0, count) - args := make([][]interface{}, 0, count) + args := make([][]any, 0, count) // upsert table status for _, state := range tableStatus { @@ -262,7 +262,7 @@ func (c *validatorPersistHelper) persistTableStatusAndErrors(tctx *tcontext.Cont message = VALUES(message) ` queries = append(queries, query) - args = append(args, []interface{}{ + args = append(args, []any{ c.cfg.SourceID, state.source.Schema, state.source.Name, state.target.Schema, state.target.Name, int(state.stage), state.message, }, @@ -292,7 +292,7 @@ func (c *validatorPersistHelper) persistTableStatusAndErrors(tctx *tcontext.Cont if err != nil { return err } - dstData := make([]interface{}, len(r.dstData)) + dstData := make([]any, len(r.dstData)) for i, d := range r.dstData { if d.Valid { dstData[i] = d.String @@ -304,7 +304,7 @@ func (c *validatorPersistHelper) persistTableStatusAndErrors(tctx *tcontext.Cont } sourceTable := row.GetSourceTable() targetTable := row.GetTargetTable() - args = append(args, []interface{}{ + args = append(args, []any{ c.cfg.SourceID, sourceTable.Schema, sourceTable.Table, r.srcJob.Key, targetTable.Schema, targetTable.Table, string(srcDataBytes), string(dstDataBytes), r.tp, pb.ValidateErrorState_NewErr, @@ -318,11 +318,11 @@ func (c *validatorPersistHelper) persistTableStatusAndErrors(tctx *tcontext.Cont func (c *validatorPersistHelper) persistPendingRows(tctx *tcontext.Context, rev int64) error { count := int(c.validator.getAllPendingRowCount()) + 1 queries := make([]string, 0, count) - args := make([][]interface{}, 0, count) + args := make([][]any, 0, count) // delete pending rows left by previous failed call of "persist" queries = append(queries, `DELETE FROM `+c.pendingChangeTableName+` WHERE source = ? and revision = ?`) - args = append(args, []interface{}{c.cfg.SourceID, rev}) + args = append(args, []any{c.cfg.SourceID, rev}) // insert pending row changes with revision=rev for _, worker := range c.validator.getWorkers() { for _, tblChange := range worker.getPendingChangesMap() { @@ -344,7 +344,7 @@ func (c *validatorPersistHelper) persistPendingRows(tctx *tcontext.Context, rev (source, schema_name, table_name, row_pk, data, revision) VALUES (?, ?, ?, ?, ?, ?)` queries = append(queries, query) sourceTable := row.GetSourceTable() - args = append(args, []interface{}{ + args = append(args, []any{ c.cfg.SourceID, sourceTable.Schema, sourceTable.Table, @@ -393,12 +393,12 @@ func (c *validatorPersistHelper) persist(tctx *tcontext.Context, loc binlog.Loca revision = VALUES(revision) ` rowCounts := c.validator.getProcessedRowCounts() - args := []interface{}{ + args := []any{ c.cfg.SourceID, loc.Position.Name, loc.Position.Pos, loc.GTIDSetStr(), rowCounts[rowInsert], rowCounts[rowUpdated], rowCounts[rowDeleted], nextRevision, } - if err := c.execQueriesWithRetry(newCtx, []string{query}, [][]interface{}{args}); err != nil { + if err := c.execQueriesWithRetry(newCtx, []string{query}, [][]any{args}); err != nil { return err } @@ -406,8 +406,8 @@ func (c *validatorPersistHelper) persist(tctx *tcontext.Context, loc binlog.Loca // but we need to clean up previous pending row changes, i.e. rows with different revision. // it's ok to fail here, next persist will try to delete again, so just log it. query = `DELETE FROM ` + c.pendingChangeTableName + ` WHERE source = ? and revision != ?` - args = []interface{}{c.cfg.SourceID, nextRevision} - if err := c.execQueriesWithRetry(newCtx, []string{query}, [][]interface{}{args}); err != nil { + args = []any{c.cfg.SourceID, nextRevision} + if err := c.execQueriesWithRetry(newCtx, []string{query}, [][]any{args}); err != nil { c.L.Warn("failed to delete previous pending row changes", zap.Error(err), zap.Reflect("args", args)) // nolint:nilerr } @@ -430,7 +430,7 @@ func (c *validatorPersistHelper) loadPersistedDataRetry(tctx *tcontext.Context) start := time.Now() newCtx, cancelFunc := tctx.WithTimeout(validationDBTimeout) defer cancelFunc() - workFunc := func(tctx *tcontext.Context) (interface{}, error) { + workFunc := func(tctx *tcontext.Context) (any, error) { return c.loadPersistedData(tctx) } ret, i, err := c.retryer.Apply(newCtx, workFunc) @@ -637,7 +637,7 @@ func (c *validatorPersistHelper) loadError(tctx *tcontext.Context, db *conn.Base err error ) res := make([]*pb.ValidationError, 0) - args := []interface{}{ + args := []any{ c.cfg.SourceID, } query := "SELECT id, source, src_schema_name, src_table_name, dst_schema_name, dst_table_name, data, dst_data, error_type, status, update_time " + @@ -696,7 +696,7 @@ func (c *validatorPersistHelper) operateError(tctx *tcontext.Context, db *conn.B c.L.Warn("unsupported validator error operation", zap.Reflect("op", validateOp)) return nil } - args := []interface{}{ + args := []any{ int(setStatus), c.cfg.SourceID, } @@ -710,7 +710,7 @@ func (c *validatorPersistHelper) operateError(tctx *tcontext.Context, db *conn.B } func (c *validatorPersistHelper) deleteError(tctx *tcontext.Context, db *conn.BaseDB, errID uint64, isAll bool) error { - args := []interface{}{ + args := []any{ c.cfg.SourceID, } query := "DELETE FROM " + c.errorChangeTableName + " WHERE source=?" diff --git a/dm/syncer/validator_checkpoint_test.go b/dm/syncer/validator_checkpoint_test.go index 6f4f843ac7..00f93289cf 100644 --- a/dm/syncer/validator_checkpoint_test.go +++ b/dm/syncer/validator_checkpoint_test.go @@ -125,9 +125,9 @@ func TestValidatorCheckpointPersist(t *testing.T) { validator.workers[0].errorRows = append(validator.workers[0].errorRows, &validateFailedRow{ tp: deletedRowExists, dstData: []*sql.NullString{{String: "1", Valid: true}, {String: "a", Valid: true}}, - srcJob: genRowChangeJob(tbl, tblInfo, "1", rowDeleted, []interface{}{1, "a"}), + srcJob: genRowChangeJob(tbl, tblInfo, "1", rowDeleted, []any{1, "a"}), }) - validator.dispatchRowChange("1", genRowChangeJob(tbl, tblInfo, "1", rowInsert, []interface{}{1, "a"})) + validator.dispatchRowChange("1", genRowChangeJob(tbl, tblInfo, "1", rowInsert, []any{1, "a"})) validator.newErrorRowCount.Store(1) // fail on first persist @@ -179,7 +179,7 @@ func TestValidatorCheckpointPersist(t *testing.T) { validator.workers[0].errorRows = append(validator.workers[0].errorRows, &validateFailedRow{ tp: deletedRowExists, dstData: []*sql.NullString{{String: "1", Valid: true}, {String: "a", Valid: true}}, - srcJob: genRowChangeJob(tbl, tblInfo, "1", rowDeleted, []interface{}{1, "a"}), + srcJob: genRowChangeJob(tbl, tblInfo, "1", rowDeleted, []any{1, "a"}), }) validator.newErrorRowCount.Store(1) validator.flushedLoc = nil diff --git a/dm/syncer/validator_cond.go b/dm/syncer/validator_cond.go index 4c4d0e04a6..edff8d5890 100644 --- a/dm/syncer/validator_cond.go +++ b/dm/syncer/validator_cond.go @@ -26,8 +26,8 @@ type Cond struct { PkValues [][]string } -func (c *Cond) GetArgs() []interface{} { - var res []interface{} +func (c *Cond) GetArgs() []any { + var res []any for _, v := range c.PkValues { for _, val := range v { res = append(res, val) diff --git a/dm/syncer/validator_cond_test.go b/dm/syncer/validator_cond_test.go index c553f28051..73903927b7 100644 --- a/dm/syncer/validator_cond_test.go +++ b/dm/syncer/validator_cond_test.go @@ -66,7 +66,7 @@ func TestValidatorCondSelectMultiKey(t *testing.T) { ");" // get table diff pkValues := make([][]string, 0) - for i := 0; i < 3; i++ { + for i := range 3 { // 3 primary key key1, key2 := strconv.Itoa(i+1), strconv.Itoa(i+2) pkValues = append(pkValues, []string{key1, key2}) @@ -141,11 +141,11 @@ func TestValidatorCondGetWhereArgs(t *testing.T) { }, }, } - for i := 0; i < len(cases); i++ { + for i := range cases { cond := genValidationCond(t, cases[i].schemaName, cases[i].tblName, cases[i].creatTbl, cases[i].pks) require.Equal(t, cases[i].where, cond.GetWhere()) rawArgs := cond.GetArgs() - for j := 0; j < 3; j++ { + for j := range 3 { curData := fmt.Sprintf("%v", rawArgs[j]) require.Equal(t, cases[i].args[j], curData) } diff --git a/dm/unit/unit.go b/dm/unit/unit.go index 5198109371..cb5e7b2124 100644 --- a/dm/unit/unit.go +++ b/dm/unit/unit.go @@ -62,7 +62,7 @@ type Unit interface { // Status returns the unit's current status. The result may need calculation with source status, like estimated time // to catch up. If sourceStatus is nil, the calculation should be skipped. - Status(sourceStatus *binlog.SourceStatus) interface{} + Status(sourceStatus *binlog.SourceStatus) any // Type returns the unit's type Type() pb.UnitType // IsFreshTask return whether is a fresh task (not processed before) diff --git a/dm/worker/join.go b/dm/worker/join.go index 476e007723..582f2e92a3 100644 --- a/dm/worker/join.go +++ b/dm/worker/join.go @@ -66,7 +66,7 @@ func (s *Server) JoinMaster(endpoints []string) error { var errorStr string // retry to connect master - for i := 0; i < retryTimes; i++ { + for i := range retryTimes { for _, endpoint := range endpoints { ctx1, cancel1 := context.WithTimeout(ctx, 3*time.Second) //nolint:staticcheck diff --git a/dm/worker/relay.go b/dm/worker/relay.go index 5515368ff0..ecae2fde20 100644 --- a/dm/worker/relay.go +++ b/dm/worker/relay.go @@ -108,11 +108,9 @@ func (h *realRelayHolder) Init(ctx context.Context, interceptors []relay.PurgeIn // Start starts run the relay. func (h *realRelayHolder) Start() { - h.wg.Add(1) - go func() { - defer h.wg.Done() + h.wg.Go(func() { h.run() - }() + }) } // Close closes the holder. @@ -213,11 +211,9 @@ func (h *realRelayHolder) resumeRelay(_ context.Context, op pb.RelayOp) error { return terror.ErrWorkerRelayStageNotValid.Generate(h.stage, pb.Stage_Paused, op) } - h.wg.Add(1) - go func() { - defer h.wg.Done() + h.wg.Go(func() { h.run() - }() + }) return nil } diff --git a/dm/worker/relay_test.go b/dm/worker/relay_test.go index 88232e42cf..5f50af4f0b 100644 --- a/dm/worker/relay_test.go +++ b/dm/worker/relay_test.go @@ -113,12 +113,12 @@ func (d *DummyRelay) Resume(ctx context.Context, pr chan pb.ProcessResult) {} func (d *DummyRelay) Pause() {} // Error implements Process interface. -func (d *DummyRelay) Error() interface{} { +func (d *DummyRelay) Error() any { return d.errorInfo } // Status implements Process interface. -func (d *DummyRelay) Status(sourceStatus *binlog.SourceStatus) interface{} { +func (d *DummyRelay) Status(sourceStatus *binlog.SourceStatus) any { return &pb.RelayStatus{ Stage: pb.Stage_New, } diff --git a/dm/worker/server.go b/dm/worker/server.go index 5d3f813fa6..5c70928fba 100644 --- a/dm/worker/server.go +++ b/dm/worker/server.go @@ -164,11 +164,9 @@ func (s *Server) Start() error { s.setWorker(nil, true) - s.runWg.Add(1) - go func() { + s.runWg.Go(func() { s.runBackgroundJob(s.runCtx) - s.runWg.Done() - }() + }) s.startKeepAlive() diff --git a/dm/worker/server_test.go b/dm/worker/server_test.go index 8740df6c79..3cfc8add91 100644 --- a/dm/worker/server_test.go +++ b/dm/worker/server_test.go @@ -494,11 +494,9 @@ func (t *testServer) TestWatchSourceBoundEtcdCompact(c *check.C) { // step 4: watch source bound from startRev var wg sync.WaitGroup ctx1, cancel1 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { c.Assert(s.observeSourceBound(ctx1, startRev), check.IsNil) - }() + }) // step 4.1: should stop the running worker, source bound has been deleted, should stop this worker c.Assert(utils.WaitSomething(20, 100*time.Millisecond, func() bool { return s.getSourceWorker(true) == nil @@ -516,11 +514,9 @@ func (t *testServer) TestWatchSourceBoundEtcdCompact(c *check.C) { c.Assert(s.stopSourceWorker(sourceCfg.SourceID, true, true), check.IsNil) // step 5: start observeSourceBound from compacted revision again, should start worker ctx2, cancel2 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { c.Assert(s.observeSourceBound(ctx2, startRev), check.IsNil) - }() + }) c.Assert(utils.WaitSomething(30, 100*time.Millisecond, func() bool { return s.getSourceWorker(true) != nil }), check.IsTrue) @@ -751,7 +747,7 @@ func (t *testServer) TestServerDataRace(c *check.C) { defer s.Close() var wg sync.WaitGroup - for i := 0; i < 20; i++ { + for range 20 { wg.Add(2) go func() { defer wg.Done() diff --git a/dm/worker/source_worker.go b/dm/worker/source_worker.go index 4af53f8ca7..9436edd9ba 100644 --- a/dm/worker/source_worker.go +++ b/dm/worker/source_worker.go @@ -466,13 +466,11 @@ func (w *SourceWorker) EnableRelay(startBySourceCfg bool) (err error) { } // 4. watch relay stage - w.relayWg.Add(1) - go func() { - defer w.relayWg.Done() + w.relayWg.Go(func() { // TODO: handle fatal error from observeRelayStage //nolint:errcheck w.observeRelayStage(w.relayCtx, w.etcdClient, revRelay) - }() + }) w.relayEnabled.Store(true) w.l.Info("relay enabled") @@ -566,20 +564,16 @@ func (w *SourceWorker) EnableHandleSubtasks() error { } } - w.subTaskWg.Add(1) - go func() { - defer w.subTaskWg.Done() + w.subTaskWg.Go(func() { // TODO: handle fatal error from observeSubtaskStage //nolint:errcheck w.observeSubtaskStage(w.subTaskCtx, w.etcdClient, revSubTask) - }() - w.subTaskWg.Add(1) - go func() { - defer w.subTaskWg.Done() + }) + w.subTaskWg.Go(func() { // TODO: handle fatal error from observeValidatorStage //nolint:errcheck w.observeValidatorStage(w.subTaskCtx, revSubTask) - }() + }) w.subTaskEnabled.Store(true) w.l.Info("handling subtask enabled") diff --git a/dm/worker/source_worker_test.go b/dm/worker/source_worker_test.go index fe6ad63dce..bca1c341e3 100644 --- a/dm/worker/source_worker_test.go +++ b/dm/worker/source_worker_test.go @@ -448,11 +448,9 @@ func (t *testWorkerEtcdCompact) TestWatchSubtaskStageEtcdCompact(c *check.C) { c.Assert(w.subTaskHolder.findSubTask(subtaskCfg.Name), check.NotNil) var wg sync.WaitGroup ctx1, cancel1 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { c.Assert(w.observeSubtaskStage(ctx1, etcdCli, startRev), check.IsNil) - }() + }) time.Sleep(time.Second) // step 4.1: after observe, invalid subtask should be removed c.Assert(utils.WaitSomething(30, 100*time.Millisecond, func() bool { @@ -476,11 +474,9 @@ func (t *testWorkerEtcdCompact) TestWatchSubtaskStageEtcdCompact(c *check.C) { w.subTaskHolder.closeAllSubTasks() // step 5: restart observe and start from startRev, this subtask should be added ctx2, cancel2 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { c.Assert(w.observeSubtaskStage(ctx2, etcdCli, startRev), check.IsNil) - }() + }) time.Sleep(time.Second) c.Assert(utils.WaitSomething(30, 100*time.Millisecond, func() bool { return w.subTaskHolder.findSubTask(subtaskCfg.Name) != nil @@ -584,11 +580,9 @@ func (t *testWorkerEtcdCompact) TestWatchValidatorStageEtcdCompact(c *check.C) { c.Assert(getValidator(), check.IsNil) var wg sync.WaitGroup ctx1, cancel1 := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { c.Assert(w.observeValidatorStage(ctx1, startRev), check.IsNil) - }() + }) time.Sleep(time.Second) subtaskCfg.ValidatorCfg = config.ValidatorConfig{Mode: config.ValidationFast} diff --git a/dm/worker/status.go b/dm/worker/status.go index cfb83c1ac8..6b70fce81e 100644 --- a/dm/worker/status.go +++ b/dm/worker/status.go @@ -25,7 +25,7 @@ import ( ) // Status returns the status of the current sub task. -func (st *SubTask) Status() interface{} { +func (st *SubTask) Status() any { if cu := st.CurrUnit(); cu != nil { return cu.Status(nil) } diff --git a/dm/worker/subtask.go b/dm/worker/subtask.go index 971e04c4f5..56644bdb65 100644 --- a/dm/worker/subtask.go +++ b/dm/worker/subtask.go @@ -15,6 +15,7 @@ package worker import ( "context" + "slices" "sync" "time" @@ -165,7 +166,7 @@ func (st *SubTask) initUnits(relay relay.Process) error { if err != nil { initializeUnitSuccess = false // when init fail, other units initialized before should be closed - for j := 0; j < i; j++ { + for j := range i { needCloseUnits = append(needCloseUnits, st.units[j]) } return terror.Annotatef(err, "fail to initialize unit %s of subtask %s ", u.Type(), st.cfg.Name) @@ -491,10 +492,8 @@ func (st *SubTask) stageCAS(oldStage, newStage pb.Stage) bool { func (st *SubTask) setStageIfNotIn(oldStages []pb.Stage, newStage pb.Stage) bool { st.Lock() defer st.Unlock() - for _, s := range oldStages { - if st.stage == s { - return false - } + if slices.Contains(oldStages, st.stage) { + return false } st.stage = newStage updateTaskMetric(st.cfg.Name, st.cfg.SourceID, st.stage, st.workerName) @@ -505,12 +504,10 @@ func (st *SubTask) setStageIfNotIn(oldStages []pb.Stage, newStage pb.Stage) bool func (st *SubTask) setStageIfIn(oldStages []pb.Stage, newStage pb.Stage) bool { st.Lock() defer st.Unlock() - for _, s := range oldStages { - if st.stage == s { - st.stage = newStage - updateTaskMetric(st.cfg.Name, st.cfg.SourceID, st.stage, st.workerName) - return true - } + if slices.Contains(oldStages, st.stage) { + st.stage = newStage + updateTaskMetric(st.cfg.Name, st.cfg.SourceID, st.stage, st.workerName) + return true } return false } diff --git a/dm/worker/subtask_holder.go b/dm/worker/subtask_holder.go index 7781216c11..7fb82aeac7 100644 --- a/dm/worker/subtask_holder.go +++ b/dm/worker/subtask_holder.go @@ -15,6 +15,7 @@ package worker import ( "context" + "maps" "sync" "github.com/pingcap/tiflow/dm/relay" @@ -105,8 +106,6 @@ func (h *subTaskHolder) getAllSubTasks() map[string]*SubTask { h.mu.RLock() defer h.mu.RUnlock() result := make(map[string]*SubTask, len(h.subTasks)) - for name, st := range h.subTasks { - result[name] = st - } + maps.Copy(result, h.subTasks) return result } diff --git a/dm/worker/subtask_test.go b/dm/worker/subtask_test.go index cc1f2e0ef5..3a6fed0ff6 100644 --- a/dm/worker/subtask_test.go +++ b/dm/worker/subtask_test.go @@ -132,7 +132,7 @@ func (m *MockUnit) Update(context.Context, *config.SubTaskConfig) error { return m.errUpdate } -func (m *MockUnit) Status(_ *binlog.SourceStatus) interface{} { +func (m *MockUnit) Status(_ *binlog.SourceStatus) any { switch m.typ { case pb.UnitType_Check: return &pb.CheckStatus{} @@ -211,7 +211,7 @@ func (u *KillOrderUnit) Resume(ctx context.Context, pr chan pb.ProcessResult) { func (u *KillOrderUnit) Update(context.Context, *config.SubTaskConfig) error { return nil } -func (u *KillOrderUnit) Status(*binlog.SourceStatus) interface{} { return &pb.SyncStatus{} } +func (u *KillOrderUnit) Status(*binlog.SourceStatus) any { return &pb.SyncStatus{} } func (u *KillOrderUnit) Type() pb.UnitType { return u.typ } @@ -250,7 +250,7 @@ func (t *testSubTask) TestSubTaskNormalUsage(c *check.C) { // finish dump c.Assert(mockDumper.InjectProcessError(context.Background(), nil), check.IsNil) - for i := 0; i < 10; i++ { + for range 10 { if st.CurrUnit().Type() == pb.UnitType_Load { break } @@ -262,7 +262,7 @@ func (t *testSubTask) TestSubTaskNormalUsage(c *check.C) { // fail loader c.Assert(mockLoader.InjectProcessError(context.Background(), errors.New("loader process error")), check.IsNil) - for i := 0; i < 10; i++ { + for range 10 { res := st.Result() if res != nil && st.Stage() == pb.Stage_Paused { break @@ -325,7 +325,7 @@ func (t *testSubTask) TestSubTaskNormalUsage(c *check.C) { // finish loader c.Assert(mockLoader.InjectProcessError(context.Background(), nil), check.IsNil) - for i := 0; i < 1000; i++ { + for range 1000 { if st.Stage() == pb.Stage_Finished { break } @@ -655,7 +655,7 @@ func TestSubtaskRace(t *testing.T) { tempQueryStatusResponse.SubTaskStatus[0] = &tempSubTaskStatus st.result.IsCanceled = false go func() { - for i := 0; i < 10; i++ { + for range 10 { _, _ = tempQueryStatusResponse.Marshal() } }() diff --git a/dm/worker/task_checker.go b/dm/worker/task_checker.go index 81c874d9b6..bb8e4f8a8e 100644 --- a/dm/worker/task_checker.go +++ b/dm/worker/task_checker.go @@ -153,11 +153,9 @@ func (tsc *realTaskStatusChecker) Init() error { // Start implements TaskStatusChecker.Start. func (tsc *realTaskStatusChecker) Start() { - tsc.wg.Add(1) - go func() { - defer tsc.wg.Done() + tsc.wg.Go(func() { tsc.run() - }() + }) } // Close implements TaskStatusChecker.Close. diff --git a/dm/worker/task_checker_test.go b/dm/worker/task_checker_test.go index 867d54f7e2..abb0c97265 100644 --- a/dm/worker/task_checker_test.go +++ b/dm/worker/task_checker_test.go @@ -186,7 +186,7 @@ func TestCheck(t *testing.T) { latestResumeTime = rtsc.subtaskAutoResume[taskName].LatestResumeTime latestPausedTime = rtsc.subtaskAutoResume[taskName].LatestPausedTime require.Equal(t, 10*time.Second, bf.Current()) - for i := 0; i < 10; i++ { + for range 10 { rtsc.check() require.Equal(t, latestResumeTime, rtsc.subtaskAutoResume[taskName].LatestResumeTime) require.True(t, latestPausedTime.Before(rtsc.subtaskAutoResume[taskName].LatestPausedTime)) @@ -269,7 +269,7 @@ func TestCheckTaskIndependent(t *testing.T) { task1LatestResumeTime = rtsc.subtaskAutoResume[task1].LatestResumeTime task2LatestResumeTime = rtsc.subtaskAutoResume[task2].LatestResumeTime - for i := 0; i < 10; i++ { + for range 10 { time.Sleep(backoffMin) rtsc.check() require.Equal(t, task1LatestResumeTime, rtsc.subtaskAutoResume[task1].LatestResumeTime) diff --git a/engine/chaos/cases/case_fake_job.go b/engine/chaos/cases/case_fake_job.go index 80f9ed58c5..834abde405 100644 --- a/engine/chaos/cases/case_fake_job.go +++ b/engine/chaos/cases/case_fake_job.go @@ -95,7 +95,7 @@ func runFakeJobCase(ctx context.Context, cfg *config) error { mvcc := 0 interval := 60 * time.Second runTime := 10 - for i := 0; i < runTime; i++ { + for i := range runTime { value := fmt.Sprintf("update-value-index-%d", i) mvcc++ start := time.Now() @@ -119,7 +119,7 @@ func updateKeyAndCheck( ctx context.Context, cli *e2e.ChaosCli, jobID string, workerCount int, updateValue string, expectedMvcc int, ) error { - for i := 0; i < workerCount; i++ { + for i := range workerCount { err := cli.UpdateFakeJobKey(ctx, i, updateValue) if err != nil { return err @@ -127,7 +127,7 @@ func updateKeyAndCheck( } // retry 6 minutes at most finished := util.WaitSomething(60, time.Second*6, func() bool { - for jobIdx := 0; jobIdx < workerCount; jobIdx++ { + for jobIdx := range workerCount { err := cli.CheckFakeJobKey(ctx, jobID, jobIdx, expectedMvcc, updateValue) if err != nil { log.Warn("check fail job failed", zap.Error(err)) diff --git a/engine/chaos/cases/cases.go b/engine/chaos/cases/cases.go index dc185dc54e..fbe6f963b4 100644 --- a/engine/chaos/cases/cases.go +++ b/engine/chaos/cases/cases.go @@ -26,7 +26,6 @@ var cases = []caseFn{runFakeJobCase, runDMJobCases} func runCases(ctx context.Context, cfg *config) error { errg, ctx := errgroup.WithContext(ctx) for _, fn := range cases { - fn := fn errg.Go(func() error { return fn(ctx, cfg) }) diff --git a/engine/chaos/cases/dm/case.go b/engine/chaos/cases/dm/case.go index ed8100c21c..2f31b7aa8a 100644 --- a/engine/chaos/cases/dm/case.go +++ b/engine/chaos/cases/dm/case.go @@ -106,7 +106,7 @@ func NewCase(ctx context.Context, addr string, name string, cfgPath string) (*Ca for range c.sources { generators := make(map[string]sqlgen.SQLGenerator) mcps := make(map[string]*mcp.ModificationCandidatePool) - for i := 0; i < tableNum; i++ { + for i := range tableNum { tableName := fmt.Sprintf("tb%d", i) tableConfig := &sqlconfig.TableConfig{ DatabaseName: c.name, @@ -194,7 +194,7 @@ func (c *Case) genFullData() error { return err } sqls := make([]string, 0, rowNum) - for j := 0; j < rowNum; j++ { + for range rowNum { sql, uk, err := generator.GenInsertRow() if err != nil { return err @@ -244,7 +244,7 @@ func (c *Case) diffData(ctx context.Context) (bool, error) { } func (c *Case) diffDataLoop(ctx context.Context) error { - for i := 0; i < diffTimes; i++ { + for range diffTimes { select { case <-ctx.Done(): return nil @@ -329,7 +329,7 @@ func (c *Case) genIncrData(ctx context.Context) error { tableName := c.tables[rand.Intn(tableNum)] sqls := make([]string, 0, batch) - for i := 0; i < batch; i++ { + for range batch { sql, err := c.randDML(source, tableName, deleteKeys) if err != nil { return err diff --git a/engine/chaos/cases/dm/db.go b/engine/chaos/cases/dm/db.go index 71ca189d06..cf8f2adaf1 100644 --- a/engine/chaos/cases/dm/db.go +++ b/engine/chaos/cases/dm/db.go @@ -97,7 +97,7 @@ func (dc *dbConn) ExecuteSQLs(queries ...string) (int, error) { } ret, _, err := dc.con.ApplyRetryStrategy(tcontext.NewContext(ctx, log.L()), params, - func(tctx *tcontext.Context) (interface{}, error) { + func(tctx *tcontext.Context) (any, error) { ret, err2 := dc.con.ExecuteSQLWithIgnoreError(tctx, nil, "chaos-cases", ignoreExecSQLError, queries) return ret, err2 }) diff --git a/engine/executor/cvs/cvstask.go b/engine/executor/cvs/cvstask.go index c7582cb860..495e733042 100644 --- a/engine/executor/cvs/cvstask.go +++ b/engine/executor/cvs/cvstask.go @@ -72,7 +72,7 @@ func (c *connPool) getConn(addr string) (*grpc.ClientConn, error) { defer c.Unlock() arr, ok := c.pool[addr] if !ok { - for i := 0; i < 5; i++ { + for range 5 { conn, err := grpc.Dial(addr, grpc.WithInsecure()) if err != nil { return nil, err diff --git a/engine/executor/dm/unitholder.go b/engine/executor/dm/unitholder.go index 7f5d620430..dd8cbf80fe 100644 --- a/engine/executor/dm/unitholder.go +++ b/engine/executor/dm/unitholder.go @@ -43,7 +43,7 @@ type unitHolder interface { Pause(ctx context.Context) error Resume(ctx context.Context) error Stage() (metadata.TaskStage, *pb.ProcessResult) - Status(ctx context.Context) interface{} + Status(ctx context.Context) any // CheckAndUpdateStatus checks if the last update of source status is outdated, // if so, it will call Status. // this should be an async func. @@ -136,12 +136,10 @@ func (u *unitHolderImpl) Init(ctx context.Context) error { u.fieldMu.Unlock() resultCh := make(chan pb.ProcessResult, 1) - u.processWg.Add(1) - go func() { - defer u.processWg.Done() + u.processWg.Go(func() { u.unit.Process(runCtx, resultCh) u.fetchAndHandleResult(resultCh) - }() + }) return nil } @@ -183,12 +181,10 @@ func (u *unitHolderImpl) Resume(ctx context.Context) error { u.fieldMu.Unlock() resultCh := make(chan pb.ProcessResult, 1) - u.processWg.Add(1) - go func() { - defer u.processWg.Done() + u.processWg.Go(func() { u.unit.Resume(runCtx, resultCh) u.fetchAndHandleResult(resultCh) - }() + }) return nil } @@ -243,12 +239,12 @@ func (u *unitHolderImpl) Stage() (metadata.TaskStage, *pb.ProcessResult) { // Status implement UnitHolder.Status. Each invocation will try to query upstream // once and calculate the status. -func (u *unitHolderImpl) Status(ctx context.Context) interface{} { +func (u *unitHolderImpl) Status(ctx context.Context) any { // nil sourceStatus is supported return u.unit.Status(u.getSourceStatus()) } -func (u *unitHolderImpl) updateSourceStatus(ctx context.Context) interface{} { +func (u *unitHolderImpl) updateSourceStatus(ctx context.Context) any { sourceStatus, err := binlog.GetSourceStatus( tcontext.NewContext(ctx, u.logger), u.upstreamDB, @@ -279,13 +275,11 @@ func (u *unitHolderImpl) CheckAndUpdateStatus() { defer u.fieldMu.Unlock() if time.Since(u.sourceStatusCheckTime) > sourceStatusRefreshInterval { u.sourceStatusCheckTime = time.Now() - u.bgWg.Add(1) - go func() { - defer u.bgWg.Done() + u.bgWg.Go(func() { ctx, cancel := context.WithTimeout(context.Background(), sourceStatusCtxTimeOut) u.updateSourceStatus(ctx) cancel() - }() + }) } } diff --git a/engine/executor/dm/unitholder_test.go b/engine/executor/dm/unitholder_test.go index 569eddd5f8..a3a6d4d845 100644 --- a/engine/executor/dm/unitholder_test.go +++ b/engine/executor/dm/unitholder_test.go @@ -261,7 +261,7 @@ func (u *mockUnit) Update(ctx context.Context, cfg *config.SubTaskConfig) error return nil } -func (u *mockUnit) Status(sourceStatus *binlog.SourceStatus) interface{} { +func (u *mockUnit) Status(sourceStatus *binlog.SourceStatus) any { u.Lock() defer u.Unlock() return u.Called().Get(0) @@ -321,7 +321,7 @@ func (m *mockUnitHolder) Stage() (metadata.TaskStage, *pb.ProcessResult) { } // Status implement Holder.Status -func (m *mockUnitHolder) Status(ctx context.Context) interface{} { +func (m *mockUnitHolder) Status(ctx context.Context) any { m.Lock() defer m.Unlock() args := m.Called() diff --git a/engine/executor/openapi_test.go b/engine/executor/openapi_test.go index 9af73a8955..f1d28e7118 100644 --- a/engine/executor/openapi_test.go +++ b/engine/executor/openapi_test.go @@ -76,12 +76,10 @@ func TestJobAPIServer(t *testing.T) { wg := sync.WaitGroup{} stoppedJobs := make(chan engineModel.JobID, 16) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := jobAPISrv.listenStoppedJobs(context.Background(), stoppedJobs) require.NoError(t, err) - }() + }) stoppedJobs <- "job1" require.Eventually(t, func() bool { diff --git a/engine/executor/worker/task_committer.go b/engine/executor/worker/task_committer.go index 21ac6976c6..6284e9c0f2 100644 --- a/engine/executor/worker/task_committer.go +++ b/engine/executor/worker/task_committer.go @@ -85,11 +85,9 @@ func newTaskCommitterWithClock( requestTTL: requestTTL, } - committer.wg.Add(1) - go func() { - defer committer.wg.Done() + committer.wg.Go(func() { committer.runTTLChecker() - }() + }) return committer } diff --git a/engine/executor/worker/task_runner.go b/engine/executor/worker/task_runner.go index 4632279daf..2c78cf8119 100644 --- a/engine/executor/worker/task_runner.go +++ b/engine/executor/worker/task_runner.go @@ -124,7 +124,7 @@ func (r *TaskRunner) cancelAll() { } r.canceled = true - r.tasks.Range(func(key, value interface{}) bool { + r.tasks.Range(func(key, value any) bool { id := key.(RunnableID) t := value.(*taskEntry) t.cancel() diff --git a/engine/executor/worker/task_runner_test.go b/engine/executor/worker/task_runner_test.go index afb0845cde..80ba789177 100644 --- a/engine/executor/worker/task_runner_test.go +++ b/engine/executor/worker/task_runner_test.go @@ -39,16 +39,14 @@ func TestTaskRunnerBasics(t *testing.T) { tr := NewTaskRunner(workerNum+1, 1) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := tr.Run(ctx) require.Error(t, err) require.Regexp(t, "context canceled", err.Error()) - }() + }) var workers []*dummyWorker - for i := 0; i < workerNum; i++ { + for i := range workerNum { worker := &dummyWorker{ id: fmt.Sprintf("worker-%d", i), } @@ -95,13 +93,11 @@ func TestTaskRunnerSubmitTime(t *testing.T) { mockClock.Add(time.Hour) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := tr.Run(ctx) require.Error(t, err) require.Regexp(t, "context canceled", err.Error()) - }() + }) require.Eventually(t, func() bool { return worker.SubmitTime() == clock.ToMono(submitTime) @@ -117,19 +113,17 @@ func TestTaskStopReceiver(t *testing.T) { tr := NewTaskRunner(workerNum+1, 1) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := tr.Run(ctx) require.Error(t, err) require.Regexp(t, "context canceled", err.Error()) - }() + }) var ( workers []*dummyWorker running sync.Map ) - for i := 0; i < workerNum; i++ { + for i := range workerNum { worker := &dummyWorker{ id: fmt.Sprintf("worker-%d", i), } diff --git a/engine/framework/base_jobmaster.go b/engine/framework/base_jobmaster.go index 6d46c84a23..7054fafad8 100644 --- a/engine/framework/base_jobmaster.go +++ b/engine/framework/base_jobmaster.go @@ -70,7 +70,7 @@ type BaseJobMaster interface { CurrentEpoch() frameModel.Epoch // SendMessage sends a message of specific topic to jobmanager in a blocking or nonblocking way - SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error + SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error // Exit should be called when jobmaster (in user logic) wants to exit. // exitReason: ExitReasonFinished/ExitReasonCanceled/ExitReasonFailed @@ -344,7 +344,7 @@ func (d *DefaultBaseJobMaster) GetEnabledBucketStorage() (bool, resModel.Resourc } // SendMessage delegates the SendMessage or inner worker -func (d *DefaultBaseJobMaster) SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error { +func (d *DefaultBaseJobMaster) SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error { ctx, cancel := d.errCenter.WithCancelOnFirstError(ctx) defer cancel() @@ -394,7 +394,7 @@ func (j *jobMasterImplAsWorkerImpl) Tick(ctx context.Context) error { } func (j *jobMasterImplAsWorkerImpl) OnMasterMessage( - ctx context.Context, topic p2p.Topic, message interface{}, + ctx context.Context, topic p2p.Topic, message any, ) error { switch msg := message.(type) { case *frameModel.StatusChangeRequest: @@ -451,7 +451,7 @@ func (j *jobMasterImplAsMasterImpl) OnWorkerOffline(worker WorkerHandle, reason return j.inner.OnWorkerOffline(worker, reason) } -func (j *jobMasterImplAsMasterImpl) OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message interface{}) error { +func (j *jobMasterImplAsMasterImpl) OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message any) error { return j.inner.OnWorkerMessage(worker, topic, message) } diff --git a/engine/framework/base_jobmaster_test.go b/engine/framework/base_jobmaster_test.go index 4997d9c649..a1bd78390e 100644 --- a/engine/framework/base_jobmaster_test.go +++ b/engine/framework/base_jobmaster_test.go @@ -124,7 +124,7 @@ func (m *testJobMasterImpl) OnWorkerOffline(worker WorkerHandle, reason error) e return args.Error(0) } -func (m *testJobMasterImpl) OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message interface{}) error { +func (m *testJobMasterImpl) OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message any) error { m.mu.Lock() defer m.mu.Unlock() diff --git a/engine/framework/common.go b/engine/framework/common.go index fd93d8acbd..38369efc68 100644 --- a/engine/framework/common.go +++ b/engine/framework/common.go @@ -26,7 +26,7 @@ type ( WorkerType = frameModel.WorkerType // WorkerConfig stores worker config in any type - WorkerConfig = interface{} + WorkerConfig = any // WorkerHandle alias to master.WorkerHandle WorkerHandle = master.WorkerHandle diff --git a/engine/framework/internal/eventloop/runner_test.go b/engine/framework/internal/eventloop/runner_test.go index 45db21dd2d..e328ace423 100644 --- a/engine/framework/internal/eventloop/runner_test.go +++ b/engine/framework/internal/eventloop/runner_test.go @@ -118,14 +118,12 @@ func TestRunnerNormalPath(t *testing.T) { task.On("Close", mock.Anything).Return(nil).Once() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := runner.Run(context.Background()) require.Error(t, err) require.Regexp(t, "injected error", err) - }() + }) require.Eventually(t, func() bool { return task.status.Load() == toyTaskRunning @@ -153,14 +151,12 @@ func TestRunnerForcefulExit(t *testing.T) { task.On("Close", mock.Anything).Return(nil).Once() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := runner.Run(context.Background()) require.Error(t, err) require.Regexp(t, "ErrWorkerSuicide", err) - }() + }) require.Eventually(t, func() bool { return task.status.Load() == toyTaskRunning @@ -208,13 +204,11 @@ func TestRunnerStopByCancel(t *testing.T) { task.On("Stop", mock.Anything).Return(nil).Once() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := runner.Run(context.Background()) require.Error(t, err) require.Regexp(t, "worker is canceled", err) - }() + }) require.Eventually(t, func() bool { return task.status.Load() == toyTaskRunning diff --git a/engine/framework/internal/master/mock_handle.go b/engine/framework/internal/master/mock_handle.go index 9772c28886..baa1aad87b 100644 --- a/engine/framework/internal/master/mock_handle.go +++ b/engine/framework/internal/master/mock_handle.go @@ -81,7 +81,7 @@ type mockRunningHandle struct { } // SendMessage implements RunningHandle.SendMessage -func (rh mockRunningHandle) SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error { +func (rh mockRunningHandle) SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error { h := rh.handler if h.IsTombstone { return errors.ErrSendingMessageToTombstone.GenWithStackByCause(h.WorkerID) diff --git a/engine/framework/internal/master/worker_handle.go b/engine/framework/internal/master/worker_handle.go index b79891cb3e..3b0dc9435e 100644 --- a/engine/framework/internal/master/worker_handle.go +++ b/engine/framework/internal/master/worker_handle.go @@ -45,7 +45,7 @@ type RunningHandle interface { SendMessage( ctx context.Context, topic p2p.Topic, - message interface{}, + message any, nonblocking bool, ) error } @@ -94,7 +94,7 @@ func (h *runningHandleImpl) Unwrap() RunningHandle { func (h *runningHandleImpl) SendMessage( ctx context.Context, topic p2p.Topic, - message interface{}, + message any, nonblocking bool, ) error { var err error diff --git a/engine/framework/internal/master/worker_manager.go b/engine/framework/internal/master/worker_manager.go index 36f07b4cdc..fddc164067 100644 --- a/engine/framework/internal/master/worker_manager.go +++ b/engine/framework/internal/master/worker_manager.go @@ -121,13 +121,11 @@ func NewWorkerManager( timeouts: timeoutConfig, } - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { if err := ret.runBackgroundChecker(); err != nil { ret.errCenter.OnError(err) } - }() + }) return ret } @@ -489,7 +487,6 @@ func (m *WorkerManager) checkWorkerEntriesOnce() error { } for workerID, entry := range m.workerEntries { - entry := entry state := entry.State() if state == workerEntryOffline || state == workerEntryTombstone { // Prevent repeated delivery of the workerOffline event. diff --git a/engine/framework/internal/master/worker_manager_test.go b/engine/framework/internal/master/worker_manager_test.go index 7bc1a5afb5..b1b486617f 100644 --- a/engine/framework/internal/master/worker_manager_test.go +++ b/engine/framework/internal/master/worker_manager_test.go @@ -559,9 +559,7 @@ func TestWorkerSendsStaleHeartbeat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { select { case <-ctx.Done(): @@ -570,7 +568,7 @@ func TestWorkerSendsStaleHeartbeat(t *testing.T) { suite.SimulateHeartbeat("worker-1", 1, wEpoch-1, "executor-1", false) } } - }() + }) event = suite.WaitForEvent(t, "worker-1") require.Equal(t, workerOfflineEvent, event.Tp) diff --git a/engine/framework/internal/worker/master_client_test.go b/engine/framework/internal/worker/master_client_test.go index 2d15c844fb..b9c505ff70 100644 --- a/engine/framework/internal/worker/master_client_test.go +++ b/engine/framework/internal/worker/master_client_test.go @@ -91,15 +91,13 @@ func (h *masterClientTestHelper) PopHeartbeat(t *testing.T) *frameModel.Heartbea } func (h *masterClientTestHelper) SimulateWorkerClose(timeout time.Duration) { - h.wg.Add(1) - go func() { - defer h.wg.Done() + h.wg.Go(func() { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() h.closeErrCh <- h.Client.WaitClosed(ctx) - }() + }) } func (h *masterClientTestHelper) WaitWorkerClosed(t *testing.T) error { diff --git a/engine/framework/master.go b/engine/framework/master.go index b9a6988098..40c0bc8839 100644 --- a/engine/framework/master.go +++ b/engine/framework/master.go @@ -122,7 +122,7 @@ type MasterImpl interface { OnWorkerOffline(worker WorkerHandle, reason error) error // OnWorkerMessage is called when a customized message is received. - OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message interface{}) error + OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message any) error // OnWorkerStatusUpdated is called as the consequence of worker's UpdateStatus. // Return: diff --git a/engine/framework/master_test.go b/engine/framework/master_test.go index 00f7454bf0..0eb7f7410a 100644 --- a/engine/framework/master_test.go +++ b/engine/framework/master_test.go @@ -101,9 +101,7 @@ func TestMasterPollAndClose(t *testing.T) { master.On("Tick", mock.Anything).Return(nil) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { err := master.Poll(ctx) if err != nil { @@ -113,7 +111,7 @@ func TestMasterPollAndClose(t *testing.T) { } require.NoError(t, err) } - }() + }) require.Eventually(t, func() bool { return master.TickCount() > 10 diff --git a/engine/framework/message_router_test.go b/engine/framework/message_router_test.go index d49ea868bc..a98987d68b 100644 --- a/engine/framework/message_router_test.go +++ b/engine/framework/message_router_test.go @@ -61,21 +61,17 @@ func testMessageRouter(t *testing.T, suite *messageSuite) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = pool.Run(ctx) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { if err := router.Tick(ctx); err != nil { return } } - }() + }) require.Eventually(t, func() bool { if int(msgCounter.Load()) != len(suite.expected) { diff --git a/engine/framework/mock_master_impl.go b/engine/framework/mock_master_impl.go index ad604453af..d99e3db631 100644 --- a/engine/framework/mock_master_impl.go +++ b/engine/framework/mock_master_impl.go @@ -218,7 +218,7 @@ func (m *MockMasterImpl) OnWorkerOffline(worker WorkerHandle, reason error) erro } // OnWorkerMessage implements MasterImpl.OnWorkerMessage -func (m *MockMasterImpl) OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message interface{}) error { +func (m *MockMasterImpl) OnWorkerMessage(worker WorkerHandle, topic p2p.Topic, message any) error { m.mu.Lock() defer m.mu.Unlock() @@ -283,7 +283,7 @@ func (m *MockWorkerHandler) Unwrap() master.RunningHandle { } // SendMessage implements RunningHandle.SendMessage -func (m *MockWorkerHandler) SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error { +func (m *MockWorkerHandler) SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error { args := m.Called(ctx, topic, message, nonblocking) return args.Error(0) } diff --git a/engine/framework/mock_worker_util.go b/engine/framework/mock_worker_util.go index b7e44b9905..f67681b93f 100644 --- a/engine/framework/mock_worker_util.go +++ b/engine/framework/mock_worker_util.go @@ -88,7 +88,7 @@ func MockBaseWorkerCheckSendMessage( t *testing.T, worker *DefaultBaseWorker, topic p2p.Topic, - message interface{}, + message any, ) { masterNode := worker.masterClient.MasterNode() got, ok := worker.messageSender.(*p2p.MockMessageSender).TryPop(masterNode, topic) diff --git a/engine/framework/model/master.go b/engine/framework/model/master.go index 63d6f593da..7965e35a12 100644 --- a/engine/framework/model/master.go +++ b/engine/framework/model/master.go @@ -69,7 +69,7 @@ func (e MasterMetaExt) Value() (driver.Value, error) { } // Scan implements sql.Scanner. -func (e *MasterMetaExt) Scan(rawInput interface{}) error { +func (e *MasterMetaExt) Scan(rawInput any) error { // Zero the fields. *e = MasterMetaExt{} diff --git a/engine/framework/model/master_test.go b/engine/framework/model/master_test.go index 0ea8ef3624..fbd04b1806 100644 --- a/engine/framework/model/master_test.go +++ b/engine/framework/model/master_test.go @@ -98,7 +98,6 @@ func TestMasterMetaExtScan(t *testing.T) { } for i := range cases { - i := i t.Run(fmt.Sprintf("subcase-%d", i), func(t *testing.T) { t.Parallel() var ext MasterMetaExt diff --git a/engine/framework/model/worker.go b/engine/framework/model/worker.go index 14df407af7..7f7aa0354b 100644 --- a/engine/framework/model/worker.go +++ b/engine/framework/model/worker.go @@ -105,8 +105,8 @@ func (s *WorkerStatus) Unmarshal(bytes []byte) error { } // Map is used for update the orm model -func (s *WorkerStatus) Map() map[string]interface{} { - return map[string]interface{}{ +func (s *WorkerStatus) Map() map[string]any { + return map[string]any{ "project_id": s.ProjectID, "job_id": s.JobID, "id": s.ID, diff --git a/engine/framework/registry/registry.go b/engine/framework/registry/registry.go index 0f9db23e6f..f4cc06c51a 100644 --- a/engine/framework/registry/registry.go +++ b/engine/framework/registry/registry.go @@ -162,11 +162,11 @@ var ( nameOfBaseJobMaster = getTypeNameOfVarPtr(new(framework.BaseJobMaster)) ) -func getTypeNameOfVarPtr(v interface{}) string { +func getTypeNameOfVarPtr(v any) string { return reflect.TypeOf(v).Elem().Name() } -func implHasMember(impl interface{}, memberName string) bool { +func implHasMember(impl any, memberName string) bool { defer func() { if v := recover(); v != nil { log.Panic("wrong use of implHasMember", @@ -176,7 +176,7 @@ func implHasMember(impl interface{}, memberName string) bool { return reflect.ValueOf(impl).Elem().FieldByName(memberName) != reflect.Value{} } -func setImplMember(impl interface{}, memberName string, value interface{}) { +func setImplMember(impl any, memberName string, value any) { defer func() { if v := recover(); v != nil { log.Panic("wrong use of setImplMember", diff --git a/engine/framework/registry/registry_test.go b/engine/framework/registry/registry_test.go index 4272362425..026075fb98 100644 --- a/engine/framework/registry/registry_test.go +++ b/engine/framework/registry/registry_test.go @@ -100,7 +100,7 @@ func TestImplHasMember(t *testing.T) { type myImpl struct { MyMember int } - type myIface interface{} + type myIface any var iface myIface = &myImpl{} require.True(t, implHasMember(iface, "MyMember")) @@ -110,12 +110,12 @@ func TestImplHasMember(t *testing.T) { func TestSetImplMember(t *testing.T) { t.Parallel() - type MyBase interface{} + type MyBase any type myImpl struct { MyBase } - type myImplIface interface{} + type myImplIface any var iface myImplIface = &myImpl{} diff --git a/engine/framework/worker.go b/engine/framework/worker.go index df61679a93..c4f99d0f32 100644 --- a/engine/framework/worker.go +++ b/engine/framework/worker.go @@ -113,7 +113,7 @@ type BaseWorker interface { UpdateStatus(ctx context.Context, status frameModel.WorkerStatus) error // SendMessage sends a message of specific topic to master in a blocking or nonblocking way - SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error + SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error // OpenStorage creates a resource and return the resource handle OpenStorage( @@ -299,14 +299,12 @@ func (w *DefaultBaseWorker) doPreInit(ctx context.Context) (retErr error) { w.cancelPool = cancelPool w.cancelMu.Unlock() - w.wg.Add(1) - go func() { - defer w.wg.Done() + w.wg.Go(func() { err := w.pool.Run(poolCtx) w.Logger().Info("workerpool exited", zap.String("worker-id", w.id), zap.Error(err)) - }() + }) initTime := w.clock.Mono() rctx, ok := runtime.ToRuntimeCtx(ctx) @@ -487,7 +485,7 @@ func (w *DefaultBaseWorker) UpdateStatus(ctx context.Context, status frameModel. func (w *DefaultBaseWorker) SendMessage( ctx context.Context, topic p2p.Topic, - message interface{}, + message any, nonblocking bool, ) error { var err error @@ -553,21 +551,17 @@ func (w *DefaultBaseWorker) startBackgroundTasks() { w.cancelBgTasks = cancel w.cancelMu.Unlock() - w.wg.Add(1) - go func() { - defer w.wg.Done() + w.wg.Go(func() { if err := w.runHeartbeatWorker(ctx); err != nil { w.onError(err) } - }() + }) - w.wg.Add(1) - go func() { - defer w.wg.Done() + w.wg.Go(func() { if err := w.runWatchDog(ctx); err != nil { w.onError(err) } - }() + }) } func (w *DefaultBaseWorker) runHeartbeatWorker(ctx context.Context) error { diff --git a/engine/framework/worker_test.go b/engine/framework/worker_test.go index 9583ca6de8..5acaff63ea 100644 --- a/engine/framework/worker_test.go +++ b/engine/framework/worker_test.go @@ -138,7 +138,7 @@ func TestWorkerHeartbeatPingPong(t *testing.T) { worker.On("Tick", mock.Anything).Return(nil) var lastHeartbeatSendTime clock.MonotonicTime - for i := 0; i < heartbeatPingPongTestRepeatTimes; i++ { + for range heartbeatPingPongTestRepeatTimes { err := worker.Poll(ctx) require.NoError(t, err) @@ -394,11 +394,9 @@ func TestWorkerGracefulExit(t *testing.T) { require.Regexp(t, ".*fake error.*", err) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t, worker.NotifyExit(ctx, err)) - }() + }) for { // Make the heartbeat worker tick. @@ -465,14 +463,12 @@ func TestWorkerGracefulExitWhileTimeout(t *testing.T) { wg sync.WaitGroup ) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer done.Store(true) err := worker.NotifyExit(ctx, err) require.Error(t, err) require.Regexp(t, "context deadline exceeded", err) - }() + }) for { // Make the heartbeat worker tick. diff --git a/engine/internal/pkg/discovery/agent_test.go b/engine/internal/pkg/discovery/agent_test.go index f496a719bc..cd8798e66a 100644 --- a/engine/internal/pkg/discovery/agent_test.go +++ b/engine/internal/pkg/discovery/agent_test.go @@ -72,13 +72,11 @@ func TestAgent(t *testing.T) { defer cancel() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := agent.Run(ctx) require.ErrorIs(t, err, context.Canceled) - }() + }) initialSnap := Snapshot{ "master-1": Node{ diff --git a/engine/jobmaster/cvsjob/cvs_job_master.go b/engine/jobmaster/cvsjob/cvs_job_master.go index c4e9d0e7f9..74cf12f7de 100644 --- a/engine/jobmaster/cvsjob/cvs_job_master.go +++ b/engine/jobmaster/cvsjob/cvs_job_master.go @@ -118,7 +118,7 @@ func (jm *JobMaster) InitImpl(ctx context.Context) (err error) { } log.Info("cvs jobmaster list file success", zap.Any("id", jm.workerID), zap.Any("file number", filesNum)) // todo: store the jobmaster information into the metastore - for idx := 0; idx < filesNum; idx++ { + for idx := range filesNum { jm.jobStatus.FileInfos[idx] = &SyncFileInfo{Idx: idx} jm.syncFilesInfo[idx] = &WorkerInfo{ needCreate: *atomic.NewBool(true), diff --git a/engine/jobmaster/dm/api.go b/engine/jobmaster/dm/api.go index 960ebd5205..6fe753a8e7 100644 --- a/engine/jobmaster/dm/api.go +++ b/engine/jobmaster/dm/api.go @@ -103,9 +103,7 @@ func (jm *JobMaster) QueryJobStatus(ctx context.Context, tasks []string) (*JobSt unitState, existUnitState = state.(*metadata.UnitState) for _, task := range tasks { taskID := task - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { var ( queryStatusResp *dmpkg.QueryStatusResponse @@ -150,7 +148,7 @@ func (jm *JobMaster) QueryJobStatus(ctx context.Context, tasks []string) (*JobSt Duration: duration, } mu.Unlock() - }() + }) } wg.Wait() @@ -234,9 +232,7 @@ func (jm *JobMaster) Binlog(ctx context.Context, req *dmpkg.BinlogRequest) (*dmp ) for _, task := range req.Sources { taskID := task - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { req := &dmpkg.BinlogTaskRequest{ Op: req.Op, BinlogPos: req.BinlogPos, @@ -246,7 +242,7 @@ func (jm *JobMaster) Binlog(ctx context.Context, req *dmpkg.BinlogRequest) (*dmp mu.Lock() binlogResp.Results[taskID] = resp mu.Unlock() - }() + }) } wg.Wait() return binlogResp, nil @@ -277,9 +273,7 @@ func (jm *JobMaster) BinlogSchema(ctx context.Context, req *dmpkg.BinlogSchemaRe ) for _, task := range req.Sources { taskID := task - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { req := &dmpkg.BinlogSchemaTaskRequest{ Op: req.Op, Source: taskID, @@ -295,7 +289,7 @@ func (jm *JobMaster) BinlogSchema(ctx context.Context, req *dmpkg.BinlogSchemaRe mu.Lock() binlogSchemaResponse.Results[taskID] = resp mu.Unlock() - }() + }) } wg.Wait() return binlogSchemaResponse diff --git a/engine/jobmaster/dm/ddl_coordinator.go b/engine/jobmaster/dm/ddl_coordinator.go index 08682f947f..57af0b5201 100644 --- a/engine/jobmaster/dm/ddl_coordinator.go +++ b/engine/jobmaster/dm/ddl_coordinator.go @@ -15,6 +15,7 @@ package dm import ( "context" + "maps" "strings" "sync" @@ -618,9 +619,7 @@ func (g *shardGroup) allTableLarger(tp tableType) bool { } func (g *shardGroup) resolveTables() { - for sourceTable, conflictStmt := range g.conflictTables { - g.normalTables[sourceTable] = conflictStmt - } + maps.Copy(g.normalTables, g.conflictTables) g.conflictTables = make(map[metadata.SourceTable]string) // TODO: redirect for conflict worker. } diff --git a/engine/jobmaster/dm/ddl_coordinator_test.go b/engine/jobmaster/dm/ddl_coordinator_test.go index b4e9b04d53..bc7dde147f 100644 --- a/engine/jobmaster/dm/ddl_coordinator_test.go +++ b/engine/jobmaster/dm/ddl_coordinator_test.go @@ -17,6 +17,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "testing" "github.com/pingcap/log" @@ -838,14 +839,15 @@ func TestGCDroppedColumns(t *testing.T) { } func genCreateStmt(cols ...string) string { - str := "CREATE TABLE tbl(" + var str strings.Builder + str.WriteString("CREATE TABLE tbl(") for idx, col := range cols { if idx == 0 { - str += col + str.WriteString(col) } else { - str += ", " + col + str.WriteString(", " + col) } } - str += ")" - return str + str.WriteString(")") + return str.String() } diff --git a/engine/jobmaster/dm/dm_jobmaster.go b/engine/jobmaster/dm/dm_jobmaster.go index c98b417a30..4df40b082a 100644 --- a/engine/jobmaster/dm/dm_jobmaster.go +++ b/engine/jobmaster/dm/dm_jobmaster.go @@ -296,7 +296,7 @@ func (jm *JobMaster) OnWorkerStatusUpdated(worker framework.WorkerHandle, newSta } // OnJobManagerMessage implements JobMasterImpl.OnJobManagerMessage -func (jm *JobMaster) OnJobManagerMessage(topic p2p.Topic, message interface{}) error { +func (jm *JobMaster) OnJobManagerMessage(topic p2p.Topic, message any) error { // TODO: receive user request return nil } @@ -307,12 +307,12 @@ func (jm *JobMaster) OnOpenAPIInitialized(router *gin.RouterGroup) { } // OnWorkerMessage implements JobMasterImpl.OnWorkerMessage -func (jm *JobMaster) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message interface{}) error { +func (jm *JobMaster) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message any) error { return nil } // OnMasterMessage implements JobMasterImpl.OnMasterMessage -func (jm *JobMaster) OnMasterMessage(ctx context.Context, topic p2p.Topic, message interface{}) error { +func (jm *JobMaster) OnMasterMessage(ctx context.Context, topic p2p.Topic, message any) error { return nil } diff --git a/engine/jobmaster/dm/dm_jobmaster_test.go b/engine/jobmaster/dm/dm_jobmaster_test.go index 127623222d..4d257a4b36 100644 --- a/engine/jobmaster/dm/dm_jobmaster_test.go +++ b/engine/jobmaster/dm/dm_jobmaster_test.go @@ -192,7 +192,7 @@ func (t *testDMJobmasterSuite) TestDMJobmaster() { mockCheckpointAgent := &MockCheckpointAgent{} checkpoint.NewCheckpointAgent = func(string, *zap.Logger) checkpoint.Agent { return mockCheckpointAgent } mockMessageAgent := &dmpkg.MockMessageAgent{} - dmpkg.NewMessageAgent = func(id string, commandHandler interface{}, messageHandlerManager p2p.MessageHandlerManager, pLogger *zap.Logger) dmpkg.MessageAgent { + dmpkg.NewMessageAgent = func(id string, commandHandler any, messageHandlerManager p2p.MessageHandlerManager, pLogger *zap.Logger) dmpkg.MessageAgent { return mockMessageAgent } defer func() { @@ -284,7 +284,7 @@ func (t *testDMJobmasterSuite) TestDMJobmaster() { Result: &dmpb.ProcessResult{IsCanceled: false}, Status: loadStatusBytes, } - jm.workerManager.workerStatusMap.Range(func(key, val interface{}) bool { + jm.workerManager.workerStatusMap.Range(func(key, val any) bool { if val.(runtime.WorkerStatus).ID == worker1 { taskStatus1.Task = key.(string) } else { @@ -382,11 +382,9 @@ func (t *testDMJobmasterSuite) TestDMJobmaster() { mockMessageAgent.On("SendMessage").Return(nil).Twice() mockBaseJobmaster.On("Exit").Return(nil).Once() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { require.NoError(t.T(), jm.OnCancel(context.Background())) - }() + }) require.Eventually(t.T(), func() bool { mockMessageAgent.Lock() if len(mockMessageAgent.Calls) == 4 { @@ -419,7 +417,7 @@ func TestDuplicateFinishedState(t *testing.T) { mockCheckpointAgent := &MockCheckpointAgent{} checkpoint.NewCheckpointAgent = func(string, *zap.Logger) checkpoint.Agent { return mockCheckpointAgent } mockMessageAgent := &dmpkg.MockMessageAgent{} - dmpkg.NewMessageAgent = func(id string, commandHandler interface{}, messageHandlerManager p2p.MessageHandlerManager, pLogger *zap.Logger) dmpkg.MessageAgent { + dmpkg.NewMessageAgent = func(id string, commandHandler any, messageHandlerManager p2p.MessageHandlerManager, pLogger *zap.Logger) dmpkg.MessageAgent { return mockMessageAgent } defer func() { diff --git a/engine/jobmaster/dm/metadata/state.go b/engine/jobmaster/dm/metadata/state.go index dd949f31bc..ab8e8feec0 100644 --- a/engine/jobmaster/dm/metadata/state.go +++ b/engine/jobmaster/dm/metadata/state.go @@ -26,7 +26,7 @@ import ( ) // state represents the state which need to be stored in metadata. -type state interface{} +type state any // stateFactory creates a type of state. type stateFactory interface { @@ -158,12 +158,12 @@ func (f *frameworkMetaStore) cloneState() (state, error) { return clone, nil } -var stateTp = reflect.TypeOf((*state)(nil)).Elem() +var stateTp = reflect.TypeFor[state]() // checkAllFieldsIsPublic check all fields of a state is public. func checkAllFieldsIsPublic(state state) bool { v := reflect.ValueOf(state) - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { v = v.Elem() } if v.Kind() != reflect.Struct { diff --git a/engine/jobmaster/dm/task_manager.go b/engine/jobmaster/dm/task_manager.go index 5009e21d43..c65b8091cb 100644 --- a/engine/jobmaster/dm/task_manager.go +++ b/engine/jobmaster/dm/task_manager.go @@ -131,7 +131,7 @@ func (tm *TaskManager) UpdateTaskStatus(taskStatus runtime.TaskStatus) { // TaskStatus return the task status. func (tm *TaskManager) TaskStatus() map[string]runtime.TaskStatus { result := make(map[string]runtime.TaskStatus) - tm.tasks.Range(func(key, value interface{}) bool { + tm.tasks.Range(func(key, value any) bool { result[key.(string)] = value.(runtime.TaskStatus) return true }) @@ -204,7 +204,7 @@ func (tm *TaskManager) checkAndOperateTasks(ctx context.Context, job *metadata.J // remove all tasks, usually happened when delete jobs. func (tm *TaskManager) onJobDel() { tm.logger.Info("clear all task status") - tm.tasks.Range(func(key, value interface{}) bool { + tm.tasks.Range(func(key, value any) bool { tm.tasks.Delete(key) tm.gaugeVec.DeleteLabelValues(tm.jobID, key.(string)) return true @@ -213,7 +213,7 @@ func (tm *TaskManager) onJobDel() { // remove deleted task status, usually happened when update-job delete some tasks. func (tm *TaskManager) removeTaskStatus(job *metadata.Job) { - tm.tasks.Range(func(key, value interface{}) bool { + tm.tasks.Range(func(key, value any) bool { taskID := key.(string) if _, ok := job.Tasks[taskID]; !ok { tm.logger.Info("remove task status", zap.String("task_id", taskID)) diff --git a/engine/jobmaster/dm/task_manager_test.go b/engine/jobmaster/dm/task_manager_test.go index cf00b08a0b..4df2f95600 100644 --- a/engine/jobmaster/dm/task_manager_test.go +++ b/engine/jobmaster/dm/task_manager_test.go @@ -377,10 +377,8 @@ func (t *testDMJobmasterSuite) TestTaskManager() { defer cancel() var wg sync.WaitGroup - wg.Add(1) // run task manager - go func() { - defer wg.Done() + wg.Go(func() { t := time.NewTicker(50 * time.Millisecond) for { select { @@ -390,7 +388,7 @@ func (t *testDMJobmasterSuite) TestTaskManager() { taskManager.DoTick(ctx) } } - }() + }) syncStatus1 := runtime.TaskStatus{ Unit: frameModel.WorkerDMSync, diff --git a/engine/jobmaster/dm/worker_manager.go b/engine/jobmaster/dm/worker_manager.go index a628e77a00..2468848f33 100644 --- a/engine/jobmaster/dm/worker_manager.go +++ b/engine/jobmaster/dm/worker_manager.go @@ -113,7 +113,7 @@ func (wm *WorkerManager) UpdateWorkerStatus(workerStatus runtime.WorkerStatus) { // WorkerStatus return the worker status. func (wm *WorkerManager) WorkerStatus() map[string]runtime.WorkerStatus { result := make(map[string]runtime.WorkerStatus) - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { result[key.(string)] = value.(runtime.WorkerStatus) return true }) @@ -152,7 +152,7 @@ func (wm *WorkerManager) TickImpl(ctx context.Context) error { // remove offline worker status, usually happened when worker is offline. func (wm *WorkerManager) removeOfflineWorkers() { - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { worker := value.(runtime.WorkerStatus) if worker.IsOffline() { wm.logger.Info("remove offline worker status", zap.String("task_id", worker.TaskID)) @@ -168,7 +168,7 @@ func (wm *WorkerManager) removeOfflineWorkers() { // stop all workers, usually happened when delete jobs. func (wm *WorkerManager) onJobDel(ctx context.Context) error { var recordError error - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { workerStatus := value.(runtime.WorkerStatus) if workerStatus.IsTombStone() { return true @@ -185,7 +185,7 @@ func (wm *WorkerManager) onJobDel(ctx context.Context) error { // stop unneeded workers, usually happened when update-job delete some tasks. func (wm *WorkerManager) stopUnneededWorkers(ctx context.Context, job *metadata.Job) error { var recordError error - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { taskID := key.(string) if _, ok := job.Tasks[taskID]; !ok { workerStatus := value.(runtime.WorkerStatus) @@ -205,7 +205,7 @@ func (wm *WorkerManager) stopUnneededWorkers(ctx context.Context, job *metadata. // stop outdated workers, usually happened when update job cfgs. func (wm *WorkerManager) stopOutdatedWorkers(ctx context.Context, job *metadata.Job) error { var recordError error - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { taskID := key.(string) workerStatus := value.(runtime.WorkerStatus) task, ok := job.Tasks[taskID] @@ -418,7 +418,7 @@ func (wm *WorkerManager) stopWorker(ctx context.Context, taskID string, workerID } func (wm *WorkerManager) removeWorkerStatusByWorkerID(workerID frameModel.WorkerID) { - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { if value.(runtime.WorkerStatus).ID == workerID { wm.workerStatusMap.Delete(key) return false @@ -429,7 +429,7 @@ func (wm *WorkerManager) removeWorkerStatusByWorkerID(workerID frameModel.Worker func (wm *WorkerManager) allTombStone() bool { result := true - wm.workerStatusMap.Range(func(key, value interface{}) bool { + wm.workerStatusMap.Range(func(key, value any) bool { workerStatus := value.(runtime.WorkerStatus) if !workerStatus.IsTombStone() { result = false diff --git a/engine/jobmaster/dm/worker_manager_test.go b/engine/jobmaster/dm/worker_manager_test.go index 3a3462f108..b046de773e 100644 --- a/engine/jobmaster/dm/worker_manager_test.go +++ b/engine/jobmaster/dm/worker_manager_test.go @@ -488,10 +488,8 @@ func (t *testDMJobmasterSuite) TestWorkerManager() { workerAgent.On("CreateWorker").Return(worker2, nil).Once() var wg sync.WaitGroup - wg.Add(1) // run worker manager - go func() { - defer wg.Done() + wg.Go(func() { t := time.NewTicker(50 * time.Millisecond) for { select { @@ -501,7 +499,7 @@ func (t *testDMJobmasterSuite) TestWorkerManager() { workerManager.DoTick(ctx) } } - }() + }) // first check require.Eventually(t.T(), func() bool { @@ -618,7 +616,7 @@ type MockWorkerAgent struct { } func (mockAgent *MockWorkerAgent) CreateWorker( - workerType framework.WorkerType, taskCfg interface{}, + workerType framework.WorkerType, taskCfg any, opts ...framework.CreateWorkerOpt, ) (frameModel.WorkerID, error) { mockAgent.Lock() diff --git a/engine/jobmaster/example/master_impl.go b/engine/jobmaster/example/master_impl.go index 2af2747657..a8e431dbb3 100644 --- a/engine/jobmaster/example/master_impl.go +++ b/engine/jobmaster/example/master_impl.go @@ -98,7 +98,7 @@ func (e *exampleMaster) OnWorkerOffline(worker framework.WorkerHandle, reason er return nil } -func (e *exampleMaster) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message interface{}) error { +func (e *exampleMaster) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message any) error { log.Info("OnWorkerMessage") return nil } diff --git a/engine/jobmaster/fakejob/job_master.go b/engine/jobmaster/fakejob/job_master.go index efc42993c9..1a15cca260 100644 --- a/engine/jobmaster/fakejob/job_master.go +++ b/engine/jobmaster/fakejob/job_master.go @@ -466,7 +466,7 @@ func (m *Master) OnWorkerOffline(worker framework.WorkerHandle, reason error) er } // OnWorkerMessage implements MasterImpl.OnWorkerMessage -func (m *Master) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message interface{}) error { +func (m *Master) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message any) error { log.Info("FakeMaster: OnWorkerMessage", zap.String("topic", topic), zap.Any("message", message)) diff --git a/engine/pkg/client/executor_group_test.go b/engine/pkg/client/executor_group_test.go index ae68a141ad..2f8979324b 100644 --- a/engine/pkg/client/executor_group_test.go +++ b/engine/pkg/client/executor_group_test.go @@ -104,14 +104,12 @@ func TestGetExecutorBlocked(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer cancel() cli, err := group.GetExecutorClientB(ctx, "executor-1") require.NoError(t, err) require.NotNil(t, cli) - }() + }) time.Sleep(10 * time.Millisecond) err := group.AddExecutor("executor-1", "test-addr:1234") @@ -202,12 +200,10 @@ func TestGetExecutorBCanceled(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 := group.GetExecutorClientB(ctx, "executor-1") require.Error(t, err) - }() + }) time.Sleep(10 * time.Millisecond) cancel() diff --git a/engine/pkg/client/internal/call_test.go b/engine/pkg/client/internal/call_test.go index ca82928f25..286662f36a 100644 --- a/engine/pkg/client/internal/call_test.go +++ b/engine/pkg/client/internal/call_test.go @@ -59,15 +59,13 @@ func TestCallFuncCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { resp, err := call.Do(ctx) require.Nil(t, resp) require.Error(t, err) require.ErrorIs(t, err, context.Canceled) - }() + }) cancel() wg.Wait() @@ -84,15 +82,13 @@ func TestCallRetryCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { resp, err := call.Do(ctx) require.Nil(t, resp) require.Error(t, err) require.ErrorIs(t, err, context.Canceled) - }() + }) cancel() wg.Wait() diff --git a/engine/pkg/client/internal/leader_resolver.go b/engine/pkg/client/internal/leader_resolver.go index 704bf5728a..631c8d3075 100644 --- a/engine/pkg/client/internal/leader_resolver.go +++ b/engine/pkg/client/internal/leader_resolver.go @@ -75,11 +75,9 @@ func newLeaderResolverWithFollowerSorter( doneCh: make(chan struct{}), FollowerSorter: followerSorter, } - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { ret.bgUpdateServerList() - }() + }) return ret } diff --git a/engine/pkg/client/internal/leader_resolver_test.go b/engine/pkg/client/internal/leader_resolver_test.go index 23d19b9b0f..b3d66f1e4a 100644 --- a/engine/pkg/client/internal/leader_resolver_test.go +++ b/engine/pkg/client/internal/leader_resolver_test.go @@ -110,7 +110,7 @@ func TestLeaderResolverFrequentUpdate(t *testing.T) { _, err := leaderResolver.Build(resolver.Target{}, mockConn, resolver.BuildOptions{}) require.NoError(t, err) - for i := 0; i < 1000; i++ { + for range 1000 { leaderResolver.UpdateServerList(map[string]bool{ "leader": true, "follower-1": false, @@ -150,7 +150,7 @@ func TestLeaderResolverUpdateAfterClose(t *testing.T) { // Updating the server list after the resolver is closed // should not panic or deadlock. - for i := 0; i < 1000; i++ { + for range 1000 { leaderResolver.UpdateServerList(map[string]bool{ "leader": true, "follower-1": false, diff --git a/engine/pkg/client/test_util.go b/engine/pkg/client/test_util.go index a0f068c19e..36f369d633 100644 --- a/engine/pkg/client/test_util.go +++ b/engine/pkg/client/test_util.go @@ -31,7 +31,7 @@ func matchPreDispatchArgs(args *DispatchTaskArgs) gomock.Matcher { return &preDispatchArgsMatcher{args: args} } -func (m *preDispatchArgsMatcher) Matches(x interface{}) bool { +func (m *preDispatchArgsMatcher) Matches(x any) bool { // TODO match ProjectInfo req, ok := x.(*enginepb.PreDispatchTaskRequest) if !ok { @@ -77,7 +77,7 @@ func matchConfirmDispatch(requestID *string, workerID string) gomock.Matcher { } } -func (m *confirmDispatchMatcher) Matches(x interface{}) bool { +func (m *confirmDispatchMatcher) Matches(x any) bool { req, ok := x.(*enginepb.ConfirmDispatchTaskRequest) if !ok { return false diff --git a/engine/pkg/containers/slice_queue_test.go b/engine/pkg/containers/slice_queue_test.go index 6077bed0c2..269e8f18e1 100644 --- a/engine/pkg/containers/slice_queue_test.go +++ b/engine/pkg/containers/slice_queue_test.go @@ -71,12 +71,12 @@ func TestSliceQueueManyElements(t *testing.T) { const numElems = 10000 q := NewSliceQueue[int]() - for i := 0; i < numElems; i++ { + for i := range numElems { q.Push(i) } require.Equal(t, numElems, q.Size()) - for i := 0; i < numElems; i++ { + for i := range numElems { val, ok := q.Pop() require.True(t, ok) require.Equal(t, i, val) @@ -84,12 +84,12 @@ func TestSliceQueueManyElements(t *testing.T) { require.Equal(t, 0, q.Size()) // Repeat the test - for i := 0; i < numElems; i++ { + for i := range numElems { q.Push(i) } require.Equal(t, numElems, q.Size()) - for i := 0; i < numElems; i++ { + for i := range numElems { val, ok := q.Pop() require.True(t, ok) require.Equal(t, i, val) @@ -102,18 +102,14 @@ func TestSliceQueueConcurrentWriteAndRead(t *testing.T) { q := NewSliceQueue[int]() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { - for i := 0; i < numElems; i++ { + for i := range numElems { q.Push(i) } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { counter := 0 for { @@ -131,7 +127,7 @@ func TestSliceQueueConcurrentWriteAndRead(t *testing.T) { } } } - }() + }) wg.Wait() require.Equal(t, 0, q.Size()) diff --git a/engine/pkg/deps/deps.go b/engine/pkg/deps/deps.go index 689da3774f..7019cdb087 100644 --- a/engine/pkg/deps/deps.go +++ b/engine/pkg/deps/deps.go @@ -36,7 +36,7 @@ func NewDeps() *Deps { } // Provide accepts a constructor and build a value into container -func (d *Deps) Provide(constructor interface{}) error { +func (d *Deps) Provide(constructor any) error { return d.container.Provide(constructor) } @@ -44,7 +44,7 @@ func (d *Deps) Provide(constructor interface{}) error { // `func(arg1 Type1, arg2 Type2,...) (ret, error)`. // The arguments to the function is automatically filled with // the dependency injection functionality. -func (d *Deps) Construct(fn interface{}) (interface{}, error) { +func (d *Deps) Construct(fn any) (any, error) { fnTp := reflect.TypeOf(fn) if fnTp.NumOut() != 2 { log.Panic("Unexpected input type", zap.Any("type", reflect.TypeOf(fn))) @@ -73,10 +73,10 @@ func (d *Deps) Construct(fn interface{}) (interface{}, error) { } // Fill injects dependencies from Deps to params -func (d *Deps) Fill(params interface{}) error { +func (d *Deps) Fill(params any) error { invokeFnTp := reflect.FuncOf( []reflect.Type{reflect.TypeOf(params).Elem()}, - []reflect.Type{reflect.TypeOf(new(error))}, + []reflect.Type{reflect.TypeFor[*error]()}, false) invokeFn := reflect.MakeFunc(invokeFnTp, func(args []reflect.Value) (results []reflect.Value) { defer func() { diff --git a/engine/pkg/dm/message_agent.go b/engine/pkg/dm/message_agent.go index dc752c1d2d..2cd747cc5c 100644 --- a/engine/pkg/dm/message_agent.go +++ b/engine/pkg/dm/message_agent.go @@ -77,12 +77,12 @@ type message struct { ID messageID Type messageType Command string - Payload interface{} + Payload any } // client defines an interface that supports send message type client interface { - SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error + SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error } // messageMatcher implement a simple synchronous request/response message matcher since the lib currently only support asynchronous message. @@ -108,11 +108,11 @@ func (m *messageMatcher) sendRequest( clientCtx context.Context, topic p2p.Topic, command string, - req interface{}, + req any, client client, -) (interface{}, error) { +) (any, error) { msg := message{ID: m.allocID(), Type: requestTp, Command: command, Payload: req} - respCh := make(chan interface{}, 1) + respCh := make(chan any, 1) m.pendings.Store(msg.ID, respCh) defer m.pendings.Delete(msg.ID) @@ -132,20 +132,20 @@ func (m *messageMatcher) sendRequest( } // sendResponse sends a response with message ID. -func (m *messageMatcher) sendResponse(ctx context.Context, topic p2p.Topic, id messageID, command string, resp interface{}, client client) error { +func (m *messageMatcher) sendResponse(ctx context.Context, topic p2p.Topic, id messageID, command string, resp any, client client) error { msg := message{ID: id, Type: responseTp, Command: command, Payload: resp} return client.SendMessage(ctx, topic, msg, false /* nonblock */) } // onResponse receives and pairs a response message. -func (m *messageMatcher) onResponse(id messageID, resp interface{}) error { +func (m *messageMatcher) onResponse(id messageID, resp any) error { respCh, ok := m.pendings.Load(id) if !ok { return errors.Errorf("request %d not found", id) } select { - case respCh.(chan interface{}) <- resp: + case respCh.(chan any) <- resp: return nil default: } @@ -163,8 +163,8 @@ type MessageAgent interface { // RemoveClient is used when client is offline permanently, or the new client // with this clientID should be treated as a different client. RemoveClient(clientID string) error - SendMessage(ctx context.Context, clientID string, command string, msg interface{}) error - SendRequest(ctx context.Context, clientID string, command string, req interface{}) (interface{}, error) + SendMessage(ctx context.Context, clientID string, command string, msg any) error + SendRequest(ctx context.Context, clientID string, command string, req any) (any, error) } type clientGroup struct { @@ -188,7 +188,7 @@ type MessageAgentImpl struct { clients clientGroup // when receive message/request/response, // the corresponding processing method of commandHandler will be called according to the command name. - commandHandler interface{} + commandHandler any id string } @@ -198,7 +198,7 @@ type MessageAgentImpl struct { // MessageFuncType: func(ctx context.Context, msg *interface{}) error {} // RequestFuncType(1): func(ctx context.Context, req *interface{}) (resp *interface{}, err error) {} // RequestFuncType(2): func(ctx context.Context, req *interface{}) (resp *interface{}) {} -func NewMessageAgentImpl(id string, commandHandler interface{}, messageHandlerManager p2p.MessageHandlerManager, pLogger *zap.Logger) MessageAgent { +func NewMessageAgentImpl(id string, commandHandler any, messageHandlerManager p2p.MessageHandlerManager, pLogger *zap.Logger) MessageAgent { agent := &MessageAgentImpl{ messageMatcher: newMessageMatcher(), clients: clientGroup{ @@ -223,12 +223,10 @@ func NewMessageAgentImpl(id string, commandHandler interface{}, messageHandlerMa }, ) agent.ctx, agent.cancel = context.WithCancel(context.Background()) - agent.wg.Add(1) - go func() { - defer agent.wg.Done() + agent.wg.Go(func() { err := agent.pool.Run(agent.ctx) agent.logger.Info("workerpool exited", zap.Error(err)) - }() + }) return agent } @@ -308,7 +306,7 @@ func (agent *MessageAgentImpl) getClient(clientID string) (client, error) { } // SendMessage send message asynchronously. -func (agent *MessageAgentImpl) SendMessage(ctx context.Context, clientID string, command string, msg interface{}) error { +func (agent *MessageAgentImpl) SendMessage(ctx context.Context, clientID string, command string, msg any) error { client, err := agent.getClient(clientID) if err != nil { return err @@ -322,7 +320,7 @@ func (agent *MessageAgentImpl) SendMessage(ctx context.Context, clientID string, // SendRequest send request synchronously. // caller should add its own retry mechanism if needed. // caller should persist the request itself if needed. -func (agent *MessageAgentImpl) SendRequest(ctx context.Context, clientID string, command string, req interface{}) (interface{}, error) { +func (agent *MessageAgentImpl) SendRequest(ctx context.Context, clientID string, command string, req any) (any, error) { agent.clients.mu.RLock() client, ok := agent.clients.clients[clientID] clientCtx, ok2 := agent.clients.ctxs[clientID] @@ -341,7 +339,7 @@ func (agent *MessageAgentImpl) SendRequest(ctx context.Context, clientID string, } // sendResponse send response asynchronously. -func (agent *MessageAgentImpl) sendResponse(ctx context.Context, clientID string, msgID messageID, command string, resp interface{}) error { +func (agent *MessageAgentImpl) sendResponse(ctx context.Context, clientID string, msgID messageID, command string, resp any) error { client, err := agent.getClient(clientID) if err != nil { return err @@ -356,7 +354,7 @@ func (agent *MessageAgentImpl) sendResponse(ctx context.Context, clientID string // Forward the response to the corresponding request. // According to the command, the corresponding message processing function of commandHandler will be called. // According to the command, the corresponding request processing function of commandHandler will be called, and send the response to caller. -func (agent *MessageAgentImpl) onMessage(topic string, msg interface{}) error { +func (agent *MessageAgentImpl) onMessage(topic string, msg any) error { agent.logger.Debug("on message", zap.String("topic", topic), zap.Any("msg", msg)) m, ok := msg.(*message) if !ok { @@ -375,7 +373,7 @@ func (agent *MessageAgentImpl) onMessage(topic string, msg interface{}) error { } // handleResponse receive response. -func (agent *MessageAgentImpl) handleResponse(id messageID, command string, resp interface{}) error { +func (agent *MessageAgentImpl) handleResponse(id messageID, command string, resp any) error { handler := reflect.ValueOf(agent.commandHandler).MethodByName(command) if !handler.IsValid() { return errors.Errorf("response handler for command %s not found", command) @@ -394,7 +392,7 @@ func (agent *MessageAgentImpl) handleResponse(id messageID, command string, resp } // handleRequest receive request, call request handler and send response. -func (agent *MessageAgentImpl) handleRequest(clientID string, msgID messageID, command string, req interface{}) error { +func (agent *MessageAgentImpl) handleRequest(clientID string, msgID messageID, command string, req any) error { handler := reflect.ValueOf(agent.commandHandler).MethodByName(command) if !handler.IsValid() { return errors.Errorf("request handler for command %s not found", command) @@ -425,7 +423,7 @@ func (agent *MessageAgentImpl) handleRequest(clientID string, msgID messageID, c } // handle message receive message and call message handler. -func (agent *MessageAgentImpl) handleMessage(command string, msg interface{}) error { +func (agent *MessageAgentImpl) handleMessage(command string, msg any) error { handler := reflect.ValueOf(agent.commandHandler).MethodByName(command) if !handler.IsValid() { return errors.Errorf("message handler for command %s not found", command) diff --git a/engine/pkg/dm/message_agent_test.go b/engine/pkg/dm/message_agent_test.go index d4f61739f5..bc50b75e13 100644 --- a/engine/pkg/dm/message_agent_test.go +++ b/engine/pkg/dm/message_agent_test.go @@ -38,14 +38,12 @@ func TestAllocID(t *testing.T) { require.Equal(t, messageID(3), messageMatcher.allocID()) var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() - for i := 0; i < 100; i++ { + for range 10 { + wg.Go(func() { + for range 100 { messageMatcher.allocID() } - }() + }) } wg.Wait() require.Equal(t, messageID(1004), messageMatcher.allocID()) @@ -56,8 +54,7 @@ func TestMessageMatcher(t *testing.T) { messageMatcher := newMessageMatcher() mockClient := &MockClient{} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() clientCtx := context.Background() @@ -291,7 +288,7 @@ type MockClient struct { mock.Mock } -func (s *MockClient) SendMessage(ctx context.Context, topic p2p.Topic, message interface{}, nonblocking bool) error { +func (s *MockClient) SendMessage(ctx context.Context, topic p2p.Topic, message any, nonblocking bool) error { s.Lock() defer s.Unlock() args := s.Called() diff --git a/engine/pkg/dm/mock_message_agent.go b/engine/pkg/dm/mock_message_agent.go index baaf8417e2..918a48456f 100644 --- a/engine/pkg/dm/mock_message_agent.go +++ b/engine/pkg/dm/mock_message_agent.go @@ -35,7 +35,7 @@ func GenerateTopic(senderID, receiverID string) string { } // GenerateResponse generate mock response message. -func GenerateResponse(id messageID, command string, msg interface{}) interface{} { +func GenerateResponse(id messageID, command string, msg any) any { resp := message{ID: id, Type: responseTp, Command: command, Payload: msg} // nolint:errcheck bytes, _ := json.Marshal(resp) @@ -58,14 +58,14 @@ func (m *MockMessageAgent) UpdateClient(clientID string, client client) error { func (m *MockMessageAgent) RemoveClient(clientID string) error { return nil } // SendMessage implement MessageAgent.SendMessage. -func (m *MockMessageAgent) SendMessage(ctx context.Context, clientID string, command string, msg interface{}) error { +func (m *MockMessageAgent) SendMessage(ctx context.Context, clientID string, command string, msg any) error { m.Lock() defer m.Unlock() return m.Called().Error(0) } // SendRequest implement MessageAgent.SendRequest. -func (m *MockMessageAgent) SendRequest(ctx context.Context, clientID string, command string, req interface{}) (interface{}, error) { +func (m *MockMessageAgent) SendRequest(ctx context.Context, clientID string, command string, req any) (any, error) { m.Lock() defer m.Unlock() args := m.Called(ctx, clientID, command, req) diff --git a/engine/pkg/dm/ticker/ticker_test.go b/engine/pkg/dm/ticker/ticker_test.go index f0f50d9f19..06788f5581 100644 --- a/engine/pkg/dm/ticker/ticker_test.go +++ b/engine/pkg/dm/ticker/ticker_test.go @@ -34,10 +34,8 @@ func TestDefaultTicker(t *testing.T) { tickError := errors.New("tick error") dummyTicker.SetResult([]error{tickError, tickError, nil}) - wg.Add(1) // run task manager - go func() { - defer wg.Done() + wg.Go(func() { t := time.NewTicker(50 * time.Millisecond) for { select { @@ -47,7 +45,7 @@ func TestDefaultTicker(t *testing.T) { dummyTicker.DoTick(ctx) } } - }() + }) // first tick when start require.Eventually(t, dummyTicker.ResultAllMeet, 5*time.Second, 100*time.Millisecond) diff --git a/engine/pkg/errctx/center_test.go b/engine/pkg/errctx/center_test.go index 11675a4ad4..50d5e14b79 100644 --- a/engine/pkg/errctx/center_test.go +++ b/engine/pkg/errctx/center_test.go @@ -26,17 +26,15 @@ func TestErrCenterMultipleErrCtx(t *testing.T) { center := NewErrCenter() var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 10 { + wg.Go(func() { ctx, cancel := center.WithCancelOnFirstError(context.Background()) defer cancel() <-ctx.Done() require.Error(t, ctx.Err()) require.EqualError(t, ctx.Err(), "fake error") - }() + }) } center.OnError(errors.New("fake error")) @@ -53,15 +51,13 @@ func TestErrCenterSingleErrCtx(t *testing.T) { defer cancel() var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 10 { + wg.Go(func() { <-ctx.Done() require.Error(t, ctx.Err()) require.EqualError(t, ctx.Err(), "fake error") - }() + }) } center.OnError(errors.New("fake error")) diff --git a/engine/pkg/externalresource/broker/broker_integration_test.go b/engine/pkg/externalresource/broker/broker_integration_test.go index 7d66cbcc6e..2eac389ec1 100644 --- a/engine/pkg/externalresource/broker/broker_integration_test.go +++ b/engine/pkg/externalresource/broker/broker_integration_test.go @@ -371,13 +371,13 @@ func TestIntegrationBrokerGCClosedWorker(t *testing.T) { expectedGCWorkerCnt := int32(0) wg := sync.WaitGroup{} - for worker := 0; worker < workerCount; worker++ { + for worker := range workerCount { gc := rand.Intn(2) == 0 workerID := fmt.Sprintf("worker-%d", worker) resCount := rand.Intn(maxResNumPerWorker) + 1 persistedResCount := 0 - for res := 0; res < resCount; res++ { + for res := range resCount { resID := fmt.Sprintf("/s3/test-%d", res) isPersisted := rand.Intn(2) == 0 if isPersisted { diff --git a/engine/pkg/externalresource/broker/broker_test.go b/engine/pkg/externalresource/broker/broker_test.go index 8d325fb59f..6fdc1364e9 100644 --- a/engine/pkg/externalresource/broker/broker_test.go +++ b/engine/pkg/externalresource/broker/broker_test.go @@ -47,8 +47,7 @@ func newBroker(t *testing.T) (*DefaultBroker, *manager.MockClient, string) { } func TestNewBroker(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() c := client.NewMockServerMasterClient(gomock.NewController(t)) diff --git a/engine/pkg/externalresource/integration_test/mock_cluster.go b/engine/pkg/externalresource/integration_test/mock_cluster.go index 07d1938083..5d4987290d 100644 --- a/engine/pkg/externalresource/integration_test/mock_cluster.go +++ b/engine/pkg/externalresource/integration_test/mock_cluster.go @@ -82,23 +82,19 @@ func (c *mockCluster) Start(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) c.cancel = cancel - c.wg.Add(1) - go func() { - defer c.wg.Done() + c.wg.Go(func() { err := c.gcCoordinator.Run(ctx) require.Error(t, err) require.True(t, errors.Is(err, context.Canceled)) - }() + }) - c.wg.Add(1) - go func() { - defer c.wg.Done() + c.wg.Go(func() { err := c.gcRunner.Run(ctx) require.Error(t, err) require.True(t, errors.Is(err, context.Canceled)) - }() + }) } func (c *mockCluster) Stop() { diff --git a/engine/pkg/externalresource/internal/bucket/file_manager.go b/engine/pkg/externalresource/internal/bucket/file_manager.go index 0639b31b92..9cda4688a0 100644 --- a/engine/pkg/externalresource/internal/bucket/file_manager.go +++ b/engine/pkg/externalresource/internal/bucket/file_manager.go @@ -263,7 +263,7 @@ func (m *FileManager) SetPersisted( return nil } -func (m *FileManager) validateExecutor(creator model.ExecutorID, res interface{}) { +func (m *FileManager) validateExecutor(creator model.ExecutorID, res any) { if creator != m.executorID { log.Panic("inconsistent executor ID of bucket file", zap.Any("resource", res), diff --git a/engine/pkg/externalresource/internal/bucket/file_manager_integration_test.go b/engine/pkg/externalresource/internal/bucket/file_manager_integration_test.go index d9e3ccd6ec..dadee7b31b 100644 --- a/engine/pkg/externalresource/internal/bucket/file_manager_integration_test.go +++ b/engine/pkg/externalresource/internal/bucket/file_manager_integration_test.go @@ -112,7 +112,7 @@ func TestIntegrationS3FileManagerRemoveTemporaryResources(t *testing.T) { WorkerID: worker, } - for i := 0; i < numTemporaryResources; i++ { + for i := range numTemporaryResources { _, err := fm.CreateResource(ctx, internal.ResourceIdent{ ResourceScope: scope, Name: fmt.Sprintf("temp-resource-%d", i), @@ -120,7 +120,7 @@ func TestIntegrationS3FileManagerRemoveTemporaryResources(t *testing.T) { require.NoError(t, err) } - for i := 0; i < numPersistedResources; i++ { + for i := range numPersistedResources { ident := internal.ResourceIdent{ ResourceScope: scope, Name: fmt.Sprintf("persisted-resource-%d", i), @@ -138,7 +138,7 @@ func TestIntegrationS3FileManagerRemoveTemporaryResources(t *testing.T) { Executor: MockExecutorID, WorkerID: worker, } - for i := 0; i < numPersistedResources; i++ { + for i := range numPersistedResources { ident := internal.ResourceIdent{ ResourceScope: scope, Name: fmt.Sprintf("persisted-resource-%d", i), @@ -147,7 +147,7 @@ func TestIntegrationS3FileManagerRemoveTemporaryResources(t *testing.T) { require.NoError(t, err) } - for i := 0; i < numTemporaryResources; i++ { + for i := range numTemporaryResources { _, err := fm.GetPersistedResource(ctx, internal.ResourceIdent{ ResourceScope: scope, Name: fmt.Sprintf("temp-resource-%d", i), diff --git a/engine/pkg/externalresource/internal/bucket/file_path_util.go b/engine/pkg/externalresource/internal/bucket/file_path_util.go index 5899717d30..4bbba9fa59 100644 --- a/engine/pkg/externalresource/internal/bucket/file_path_util.go +++ b/engine/pkg/externalresource/internal/bucket/file_path_util.go @@ -46,7 +46,7 @@ func getPathPredByPersistedResources( ) pathPredFunc { return func(path string) bool { resPath := "" - for i := 0; i < prefixCnt; i++ { + for range prefixCnt { prefix, newPath, ok := strings.Cut(path, "/") if !ok { return false diff --git a/engine/pkg/externalresource/internal/bucket/resource_controller_test.go b/engine/pkg/externalresource/internal/bucket/resource_controller_test.go index 4478a91919..4a475842b1 100644 --- a/engine/pkg/externalresource/internal/bucket/resource_controller_test.go +++ b/engine/pkg/externalresource/internal/bucket/resource_controller_test.go @@ -36,7 +36,7 @@ func TestS3ResourceController(t *testing.T) { defer cancel() temproraryResNames := make([]resModel.ResourceName, numTemporaryResources) - for i := 0; i < numTemporaryResources; i++ { + for i := range numTemporaryResources { resID := fmt.Sprintf("/s3/temporary-resource-%d", i) _, resName, err := resModel.ParseResourceID(resID) require.NoError(t, err) @@ -45,7 +45,7 @@ func TestS3ResourceController(t *testing.T) { persistedResNames := make([]resModel.ResourceName, numPersistedResources) persistedResMetas := []*resModel.ResourceMeta{} - for i := 0; i < numPersistedResources; i++ { + for i := range numPersistedResources { resID := fmt.Sprintf("/s3/persisted-resource-%d", i) _, resName, err := resModel.ParseResourceID(resID) require.NoError(t, err) diff --git a/engine/pkg/externalresource/internal/local/file_manager.go b/engine/pkg/externalresource/internal/local/file_manager.go index 081d1e27e0..bd88bcc833 100644 --- a/engine/pkg/externalresource/internal/local/file_manager.go +++ b/engine/pkg/externalresource/internal/local/file_manager.go @@ -320,7 +320,7 @@ func PreCheckConfig(config resModel.LocalFileConfig) error { return nil } -func (m *FileManager) validateExecutor(creator model.ExecutorID, res interface{}) { +func (m *FileManager) validateExecutor(creator model.ExecutorID, res any) { // Defensive verification to ensure that local resources are not accessible across nodes. if creator != m.executorID { log.Panic("inconsistent executor ID of local file", diff --git a/engine/pkg/externalresource/internal/local/file_manager_test.go b/engine/pkg/externalresource/internal/local/file_manager_test.go index 333f9df24d..6418a9a1d6 100644 --- a/engine/pkg/externalresource/internal/local/file_manager_test.go +++ b/engine/pkg/externalresource/internal/local/file_manager_test.go @@ -135,7 +135,7 @@ func TestFileManagerManyWorkers(t *testing.T) { fm := NewLocalFileManager("", resModel.LocalFileConfig{BaseDir: dir}) ctx := context.Background() - for i := 0; i < numWorkers; i++ { + for i := range numWorkers { // For each worker, first create a persisted resource res, err := fm.CreateResource(ctx, newResourceIdentForTesting("", fmt.Sprintf("worker-%d", i), @@ -174,13 +174,13 @@ func TestFileManagerManyWorkers(t *testing.T) { } // Garbage collects about half the workers' temporary files. - for i := 0; i < numWorkers/2; i++ { + for i := range numWorkers / 2 { workerID := fmt.Sprintf("worker-%d", i) err := fm.RemoveTemporaryFiles(ctx, internal.ResourceScope{WorkerID: workerID}) require.NoError(t, err) } - for i := 0; i < numWorkers; i++ { + for i := range numWorkers { workerID := fmt.Sprintf("worker-%d", i) resourceID1 := fmt.Sprintf("resource-%d-1", i) require.DirExists(t, filepath.Join(dir, workerID, ResourceNameToFilePathName(resourceID1))) diff --git a/engine/pkg/externalresource/manager/gc_coordinator_test.go b/engine/pkg/externalresource/manager/gc_coordinator_test.go index 04d98ec0a3..330f44f03c 100644 --- a/engine/pkg/externalresource/manager/gc_coordinator_test.go +++ b/engine/pkg/externalresource/manager/gc_coordinator_test.go @@ -67,12 +67,10 @@ func newGCTestHelper() *gcTestHelper { } func (h *gcTestHelper) Start() { - h.wg.Add(1) - go func() { - defer h.wg.Done() + h.wg.Go(func() { h.errCh <- h.Coord.Run(h.ctx) - }() + }) } func (h *gcTestHelper) Close() { diff --git a/engine/pkg/externalresource/manager/gc_runner_test.go b/engine/pkg/externalresource/manager/gc_runner_test.go index d4b71cae35..da186185ee 100644 --- a/engine/pkg/externalresource/manager/gc_runner_test.go +++ b/engine/pkg/externalresource/manager/gc_runner_test.go @@ -77,12 +77,10 @@ func newGCRunnerTestHelperWithMeta(meta pkgOrm.ResourceClient) *gcRunnerTestHelp } func (h *gcRunnerTestHelper) Start() { - h.wg.Add(1) - go func() { - defer h.wg.Done() + h.wg.Go(func() { h.errCh <- h.Runner.Run(h.ctx) - }() + }) } func (h *gcRunnerTestHelper) Close() { @@ -257,7 +255,7 @@ func TestGCRunnerMultiple(t *testing.T) { resources := []string{"/local/resource", "/s3/resource"} const numResources = 1000 - for i := 0; i < numResources; i++ { + for i := range numResources { err := helper.Meta.CreateResource(context.Background(), &resModel.ResourceMeta{ ID: fmt.Sprintf("%s-%d", resources[rand.Intn(2)], i), Job: "job-1", @@ -369,7 +367,7 @@ func testGCExecutors(t *testing.T, helper *gcRunnerTestHelper) { require.NoError(t, err) } const numResources = 1000 - for i := 0; i < numResources; i++ { + for i := range numResources { workerID := rand.Intn(4) err := helper.Meta.CreateResource(context.Background(), &resModel.ResourceMeta{ ID: fmt.Sprintf("%s-%d", resources[rand.Intn(2)], i), diff --git a/engine/pkg/externalresource/manager/test_utils.go b/engine/pkg/externalresource/manager/test_utils.go index dcc8574367..52d1337906 100644 --- a/engine/pkg/externalresource/manager/test_utils.go +++ b/engine/pkg/externalresource/manager/test_utils.go @@ -15,6 +15,7 @@ package manager import ( "context" + "maps" "sync" "testing" "time" @@ -99,9 +100,7 @@ func (p *MockExecutorInfoProvider) WatchExecutors( defer p.mu.Unlock() executors := make(map[model.ExecutorID]string, len(p.executorSet)) - for id, addr := range p.executorSet { - executors[id] = addr - } + maps.Copy(executors, p.executorSet) return executors, p.notifier.NewReceiver(), nil } @@ -157,9 +156,7 @@ func (jp *MockJobStatusProvider) WatchJobStatuses( defer jp.mu.Unlock() snapCopy := make(JobStatusesSnapshot, len(jp.jobInfos)) - for k, v := range jp.jobInfos { - snapCopy[k] = v - } + maps.Copy(snapCopy, jp.jobInfos) return snapCopy, jp.notifier.NewReceiver(), nil } diff --git a/engine/pkg/externalresource/model/model.go b/engine/pkg/externalresource/model/model.go index fd12d45ecb..c847009845 100644 --- a/engine/pkg/externalresource/model/model.go +++ b/engine/pkg/externalresource/model/model.go @@ -122,8 +122,8 @@ func (m *ResourceMeta) ToQueryResourceResponse() *pb.QueryResourceResponse { } // Map is used in gorm update -func (m *ResourceMeta) Map() map[string]interface{} { - return map[string]interface{}{ +func (m *ResourceMeta) Map() map[string]any { + return map[string]any{ "project_id": m.ProjectID, "tenant_id": m.TenantID, "id": m.ID, diff --git a/engine/pkg/meta/client_test.go b/engine/pkg/meta/client_test.go index 19a348ee7e..7eb2786d03 100644 --- a/engine/pkg/meta/client_test.go +++ b/engine/pkg/meta/client_test.go @@ -37,7 +37,7 @@ func (c *errorClientConn) StoreType() metaModel.StoreType { return metaModel.StoreType("unknown") } -func (c *errorClientConn) GetConn() (interface{}, error) { +func (c *errorClientConn) GetConn() (any, error) { return nil, nil } diff --git a/engine/pkg/meta/internal/etcdkv/connection.go b/engine/pkg/meta/internal/etcdkv/connection.go index 0daf9f7510..5c382b9b33 100644 --- a/engine/pkg/meta/internal/etcdkv/connection.go +++ b/engine/pkg/meta/internal/etcdkv/connection.go @@ -48,7 +48,7 @@ type clientConnImpl struct { } // GetConn implements GetConn of ClientConn -func (cc *clientConnImpl) GetConn() (interface{}, error) { +func (cc *clientConnImpl) GetConn() (any, error) { cc.rwLock.RLock() defer cc.rwLock.RUnlock() diff --git a/engine/pkg/meta/internal/etcdkv/etcd_impl_test.go b/engine/pkg/meta/internal/etcdkv/etcd_impl_test.go index fe836981f8..7263c2d972 100644 --- a/engine/pkg/meta/internal/etcdkv/etcd_impl_test.go +++ b/engine/pkg/meta/internal/etcdkv/etcd_impl_test.go @@ -532,10 +532,8 @@ func testGenerator(t *testing.T, kvcli metaModel.KVClient) { require.GreaterOrEqual(t, firstEpoch, int64(0)) var wg sync.WaitGroup - for i := 0; i < 100; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 100 { + wg.Go(func() { epoch, err := kvcli.GenEpoch(ctx) require.Nil(t, err) require.GreaterOrEqual(t, epoch, int64(0)) @@ -544,7 +542,7 @@ func testGenerator(t *testing.T, kvcli metaModel.KVClient) { epoch, err = kvcli.GenEpoch(ctx) require.Nil(t, err) require.Greater(t, epoch, oldEpoch) - }() + }) } wg.Wait() diff --git a/engine/pkg/meta/internal/sqlkv/connection.go b/engine/pkg/meta/internal/sqlkv/connection.go index 022ab59e6e..ddb275d061 100644 --- a/engine/pkg/meta/internal/sqlkv/connection.go +++ b/engine/pkg/meta/internal/sqlkv/connection.go @@ -51,7 +51,7 @@ type clientConnImpl struct { // GetConn implements GetConn of ClientConn // Return *sql.DB if no error -func (cc *clientConnImpl) GetConn() (interface{}, error) { +func (cc *clientConnImpl) GetConn() (any, error) { cc.rwLock.RLock() defer cc.rwLock.RUnlock() diff --git a/engine/pkg/meta/internal/sqlkv/sql_impl_test.go b/engine/pkg/meta/internal/sqlkv/sql_impl_test.go index 710868caf4..ce7e76f1e5 100644 --- a/engine/pkg/meta/internal/sqlkv/sql_impl_test.go +++ b/engine/pkg/meta/internal/sqlkv/sql_impl_test.go @@ -41,12 +41,12 @@ const ( ) type tCase struct { - caseName string // case name - fn string // function name - inputs []interface{} // function args + caseName string // case name + fn string // function name + inputs []any // function args - output interface{} // function output - err error // function error + output any // function output + err error // function error mockExpectResFn func(mock sqlmock.Sqlmock) // sqlmock expectation } @@ -100,7 +100,7 @@ func TestPut(t *testing.T) { testCases := []tCase{ { fn: "Put", - inputs: []interface{}{ + inputs: []any{ "key0", "value0", }, @@ -136,7 +136,7 @@ func TestGet(t *testing.T) { { caseName: "RecordNotFoundErrReturnEmptyResp", fn: "Get", - inputs: []interface{}{ + inputs: []any{ "key0", }, output: &metaModel.GetResponse{ @@ -153,7 +153,7 @@ func TestGet(t *testing.T) { { caseName: "NormalGet", fn: "Get", - inputs: []interface{}{ + inputs: []any{ "key0", }, output: &metaModel.GetResponse{ @@ -175,7 +175,7 @@ func TestGet(t *testing.T) { { caseName: "RangeGet", fn: "Get", - inputs: []interface{}{ + inputs: []any{ "key0", metaModel.WithRange("key999"), }, @@ -203,7 +203,7 @@ func TestGet(t *testing.T) { { caseName: "FromKeyGet", fn: "Get", - inputs: []interface{}{ + inputs: []any{ "key0", metaModel.WithFromKey(), }, @@ -226,7 +226,7 @@ func TestGet(t *testing.T) { { caseName: "PrefixGet", fn: "Get", - inputs: []interface{}{ + inputs: []any{ "key0", metaModel.WithPrefix(), }, @@ -266,7 +266,7 @@ func TestDelete(t *testing.T) { testCases := []tCase{ { fn: "Delete", - inputs: []interface{}{ + inputs: []any{ "key0", }, output: &metaModel.DeleteResponse{ @@ -280,7 +280,7 @@ func TestDelete(t *testing.T) { }, { fn: "Delete", - inputs: []interface{}{ + inputs: []any{ "key0", metaModel.WithRange("key999"), }, @@ -296,7 +296,7 @@ func TestDelete(t *testing.T) { }, { fn: "Delete", - inputs: []interface{}{ + inputs: []any{ "key0", metaModel.WithFromKey(), }, @@ -311,7 +311,7 @@ func TestDelete(t *testing.T) { }, { fn: "Delete", - inputs: []interface{}{ + inputs: []any{ "key0", metaModel.WithPrefix(), }, diff --git a/engine/pkg/meta/mock/clientconn_mock.go b/engine/pkg/meta/mock/clientconn_mock.go index 8777400e37..878bba1ac5 100644 --- a/engine/pkg/meta/mock/clientconn_mock.go +++ b/engine/pkg/meta/mock/clientconn_mock.go @@ -43,7 +43,7 @@ func (c *mockClientConn) StoreType() metaModel.StoreType { return metaModel.StoreTypeMockKV } -func (c *mockClientConn) GetConn() (interface{}, error) { +func (c *mockClientConn) GetConn() (any, error) { log.Panic("SHOULD not call GetConn for mock client conn") return nil, nil } @@ -77,7 +77,7 @@ func (c *sqliteClientConn) StoreType() metaModel.StoreType { return metaModel.StoreTypeSQLite } -func (c *sqliteClientConn) GetConn() (interface{}, error) { +func (c *sqliteClientConn) GetConn() (any, error) { if c.db != nil { return c.db, nil } @@ -111,7 +111,7 @@ func (c *dbClientConn) StoreType() metaModel.StoreType { return metaModel.StoreTypeMySQL } -func (c *dbClientConn) GetConn() (interface{}, error) { +func (c *dbClientConn) GetConn() (any, error) { if c.db != nil { return c.db, nil } diff --git a/engine/pkg/meta/mock/simple_mockclient_test.go b/engine/pkg/meta/mock/simple_mockclient_test.go index c4cb7718fb..f76bd12659 100644 --- a/engine/pkg/meta/mock/simple_mockclient_test.go +++ b/engine/pkg/meta/mock/simple_mockclient_test.go @@ -179,10 +179,8 @@ func testGenerator(t *testing.T, kvcli metaModel.KVClient) { require.GreaterOrEqual(t, firstEpoch, int64(0)) var wg sync.WaitGroup - for i := 0; i < 100; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 100 { + wg.Go(func() { epoch, err := kvcli.GenEpoch(ctx) require.Nil(t, err) require.GreaterOrEqual(t, epoch, int64(0)) @@ -191,7 +189,7 @@ func testGenerator(t *testing.T, kvcli metaModel.KVClient) { epoch, err = kvcli.GenEpoch(ctx) require.Nil(t, err) require.Greater(t, epoch, oldEpoch) - }() + }) } wg.Wait() diff --git a/engine/pkg/meta/model/common.go b/engine/pkg/meta/model/common.go index f0d90fe8c8..537e78c6c5 100644 --- a/engine/pkg/meta/model/common.go +++ b/engine/pkg/meta/model/common.go @@ -15,6 +15,7 @@ package model import ( "fmt" + "strings" "github.com/pingcap/tiflow/engine/model" "github.com/pingcap/tiflow/engine/pkg/tenant" @@ -80,13 +81,14 @@ type GetResponse struct { // String only for debug func (resp *GetResponse) String() string { - s := fmt.Sprintf("header:[%s];kvs:[", resp.Header) + var s strings.Builder + s.WriteString(fmt.Sprintf("header:[%s];kvs:[", resp.Header)) for _, kv := range resp.Kvs { - s += kv.String() + s.WriteString(kv.String()) } - s += "];" - return s + s.WriteString("];") + return s.String() } // DeleteResponse . diff --git a/engine/pkg/meta/model/config.go b/engine/pkg/meta/model/config.go index 2c5ae8bd03..65891833ae 100644 --- a/engine/pkg/meta/model/config.go +++ b/engine/pkg/meta/model/config.go @@ -15,6 +15,7 @@ package model import ( "crypto/tls" + "maps" "strings" validation "github.com/go-ozzo/ozzo-validation/v4" @@ -153,9 +154,7 @@ func GenerateDSNByParams(storeConf *StoreConfig, pairs map[string]string) (strin dsnCfg.Params["writeTimeout"] = storeConf.WriteTimeout dsnCfg.Params["timeout"] = storeConf.DialTimeout - for k, v := range pairs { - dsnCfg.Params[k] = v - } + maps.Copy(dsnCfg.Params, pairs) return dsnCfg.FormatDSN(), nil } diff --git a/engine/pkg/meta/model/interfaces.go b/engine/pkg/meta/model/interfaces.go index 79ddef8481..322f9624b9 100644 --- a/engine/pkg/meta/model/interfaces.go +++ b/engine/pkg/meta/model/interfaces.go @@ -87,7 +87,7 @@ type ClientConn interface { // For the fisrt return param if no error happens: // For StoreTypeEtcd, it returns *clientv3.Client // For StoreTypeMySQL/StoreTypeSQLite, it returns *sql.DB - GetConn() (interface{}, error) + GetConn() (any, error) // Close closes the underlying connection and releases some resources Close() error diff --git a/engine/pkg/notifier/notifier.go b/engine/pkg/notifier/notifier.go index cf6ba251c2..be5d7f448a 100644 --- a/engine/pkg/notifier/notifier.go +++ b/engine/pkg/notifier/notifier.go @@ -83,11 +83,9 @@ func NewNotifier[T any]() *Notifier[T] { synchronizeCh: make(chan struct{}), } - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { ret.run() - }() + }) return ret } diff --git a/engine/pkg/notifier/notifier_test.go b/engine/pkg/notifier/notifier_test.go index 5e90fc17a5..a2ab27b6e7 100644 --- a/engine/pkg/notifier/notifier_test.go +++ b/engine/pkg/notifier/notifier_test.go @@ -34,10 +34,8 @@ func TestNotifierBasics(t *testing.T) { ) var wg sync.WaitGroup - for i := 0; i < numReceivers; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range numReceivers { + wg.Go(func() { r := n.NewReceiver() defer r.Close() @@ -55,7 +53,7 @@ func TestNotifierBasics(t *testing.T) { } lastEv = ev } - }() + }) } for i := 1; i <= numEvents; i++ { @@ -78,17 +76,15 @@ func TestNotifierClose(t *testing.T) { ) var wg sync.WaitGroup - for i := 0; i < numReceivers; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range numReceivers { + wg.Go(func() { r := n.NewReceiver() defer r.Close() _, ok := <-r.C require.False(t, ok) - }() + }) } time.Sleep(1 * time.Second) @@ -102,7 +98,7 @@ func TestReceiverClose(t *testing.T) { r := n.NewReceiver() // Send enough events to make sure the receiver channel is full. - for i := 0; i < 64; i++ { + for i := range 64 { n.Notify(i) } time.Sleep(time.Second) diff --git a/engine/pkg/orm/client.go b/engine/pkg/orm/client.go index 90f07bb7a8..1e66eb7877 100644 --- a/engine/pkg/orm/client.go +++ b/engine/pkg/orm/client.go @@ -28,7 +28,7 @@ import ( "gorm.io/gorm/clause" ) -var globalModels = []interface{}{ +var globalModels = []any{ &model.ProjectInfo{}, &model.ProjectOperation{}, &frameModel.MasterMeta{}, diff --git a/engine/pkg/orm/client_test.go b/engine/pkg/orm/client_test.go index 20d9b6d994..a3c55782be 100644 --- a/engine/pkg/orm/client_test.go +++ b/engine/pkg/orm/client_test.go @@ -42,11 +42,11 @@ const ( ) type tCase struct { - fn string // function name - inputs []interface{} // function args + fn string // function name + inputs []any // function args - output interface{} // function output - err error // function error + output any // function output + err error // function error mockExpectResFn func(mock sqlmock.Sqlmock) // sqlmock expectation } @@ -99,7 +99,7 @@ func TestProject(t *testing.T) { testCases := []tCase{ { fn: "CreateProject", - inputs: []interface{}{ + inputs: []any{ &model.ProjectInfo{ Model: model.Model{ CreatedAt: createdAt, @@ -116,7 +116,7 @@ func TestProject(t *testing.T) { }, { fn: "CreateProject", - inputs: []interface{}{ + inputs: []any{ &model.ProjectInfo{ Model: model.Model{ SeqID: 1, @@ -135,7 +135,7 @@ func TestProject(t *testing.T) { }, { fn: "DeleteProject", - inputs: []interface{}{ + inputs: []any{ "p111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -145,7 +145,7 @@ func TestProject(t *testing.T) { }, { fn: "DeleteProject", - inputs: []interface{}{ + inputs: []any{ "p111", }, mockExpectResFn: func(mock sqlmock.Sqlmock) { @@ -154,7 +154,7 @@ func TestProject(t *testing.T) { }, { fn: "QueryProjects", - inputs: []interface{}{}, + inputs: []any{}, output: []*model.ProjectInfo{ { Model: model.Model{ @@ -184,7 +184,7 @@ func TestProject(t *testing.T) { }, { fn: "QueryProjects", - inputs: []interface{}{}, + inputs: []any{}, err: errors.ErrMetaOpFail.GenWithStackByArgs(), mockExpectResFn: func(mock sqlmock.Sqlmock) { mock.ExpectQuery("SELECT [*] FROM `project_infos`").WillReturnError(errors.New("QueryProjects error")) @@ -193,7 +193,7 @@ func TestProject(t *testing.T) { { // SELECT * FROM `project_infos` WHERE project_id = '111-222-333' ORDER BY `project_infos`.`id` LIMIT 1 fn: "GetProjectByID", - inputs: []interface{}{ + inputs: []any{ "111-222-333", }, output: &model.ProjectInfo{ @@ -215,7 +215,7 @@ func TestProject(t *testing.T) { }, { fn: "GetProjectByID", - inputs: []interface{}{ + inputs: []any{ "p111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -248,7 +248,7 @@ func TestProjectOperation(t *testing.T) { { // SELECT * FROM `project_operations` WHERE project_id = '111' fn: "QueryProjectOperations", - inputs: []interface{}{ + inputs: []any{ "p111", }, output: []*model.ProjectOperation{ @@ -276,7 +276,7 @@ func TestProjectOperation(t *testing.T) { }, { fn: "QueryProjectOperations", - inputs: []interface{}{ + inputs: []any{ "p111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -287,7 +287,7 @@ func TestProjectOperation(t *testing.T) { { // SELECT * FROM `project_operations` WHERE project_id = '111' AND created_at >= '2022-04-13 23:51:42.46' AND created_at <= '2022-04-13 23:51:42.46' fn: "QueryProjectOperationsByTimeRange", - inputs: []interface{}{ + inputs: []any{ "p111", TimeRange{ start: tm, @@ -319,7 +319,7 @@ func TestProjectOperation(t *testing.T) { }, { fn: "QueryProjectOperationsByTimeRange", - inputs: []interface{}{ + inputs: []any{ "p111", TimeRange{ start: tm, @@ -367,7 +367,7 @@ func TestJob(t *testing.T) { testCases := []tCase{ { fn: "InsertJob", - inputs: []interface{}{ + inputs: []any{ &frameModel.MasterMeta{ Model: model.Model{ CreatedAt: createdAt, @@ -397,7 +397,7 @@ func TestJob(t *testing.T) { }, { fn: "InsertJob", - inputs: []interface{}{ + inputs: []any{ &frameModel.MasterMeta{ Model: model.Model{ CreatedAt: createdAt, @@ -425,7 +425,7 @@ func TestJob(t *testing.T) { }, { fn: "UpsertJob", - inputs: []interface{}{ + inputs: []any{ &frameModel.MasterMeta{ ProjectID: "p111", ID: "j111", @@ -444,7 +444,7 @@ func TestJob(t *testing.T) { }, { fn: "DeleteJob", - inputs: []interface{}{ + inputs: []any{ "j111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -457,7 +457,7 @@ func TestJob(t *testing.T) { { // DELETE FROM `master_meta` WHERE project_id = '111-222-334' AND job_id = '111' fn: "DeleteJob", - inputs: []interface{}{ + inputs: []any{ "j112", }, output: &ormResult{ @@ -471,7 +471,7 @@ func TestJob(t *testing.T) { }, { fn: "UpdateJob", - inputs: []interface{}{ + inputs: []any{ "j111", (&frameModel.MasterMeta{ ProjectID: "p111", @@ -492,7 +492,7 @@ func TestJob(t *testing.T) { }, { fn: "UpdateJob", - inputs: []interface{}{ + inputs: []any{ "j111", (&frameModel.MasterMeta{ ProjectID: "p111", @@ -513,7 +513,7 @@ func TestJob(t *testing.T) { }, { fn: "UpdateJob", - inputs: []interface{}{ + inputs: []any{ "j111", (&frameModel.MasterMeta{ ProjectID: "p111", @@ -536,7 +536,7 @@ func TestJob(t *testing.T) { }, { fn: "UpdateJob", - inputs: []interface{}{ + inputs: []any{ "j111", (&frameModel.MasterMeta{ ProjectID: "p111", @@ -560,7 +560,7 @@ func TestJob(t *testing.T) { { // SELECT * FROM `master_meta` WHERE project_id = '111-222-333' AND job_id = '111' ORDER BY `master_meta`.`id` LIMIT 1 fn: "GetJobByID", - inputs: []interface{}{ + inputs: []any{ "j111", }, output: &frameModel.MasterMeta{ @@ -592,7 +592,7 @@ func TestJob(t *testing.T) { }, { fn: "GetJobByID", - inputs: []interface{}{ + inputs: []any{ "j111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -604,7 +604,7 @@ func TestJob(t *testing.T) { { // SELECT * FROM `master_meta` WHERE project_id = '111-222-333' fn: "QueryJobsByProjectID", - inputs: []interface{}{ + inputs: []any{ "p111", }, output: []*frameModel.MasterMeta{ @@ -636,7 +636,7 @@ func TestJob(t *testing.T) { }, { fn: "QueryJobsByProjectID", - inputs: []interface{}{ + inputs: []any{ "p111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -648,7 +648,7 @@ func TestJob(t *testing.T) { { // SELECT * FROM `master_meta` WHERE project_id = '111-222-333' AND job_status = 1 fn: "QueryJobsByState", - inputs: []interface{}{ + inputs: []any{ "p111", 1, }, @@ -682,7 +682,7 @@ func TestJob(t *testing.T) { }, { fn: "QueryJobsByState", - inputs: []interface{}{ + inputs: []any{ "p111", 1, }, @@ -721,7 +721,7 @@ func TestWorker(t *testing.T) { // UPDATE `updated_at`=VALUES(`updated_at`),`project_id`=VALUES(`project_id`),`job_id`=VALUES(`job_id`),`id`=VALUES(`id`), // `type`=VALUES(`type`),`state`=VALUES(`state`),`epoch`=VALUES(`epoch`),`error_message`=VALUES(`error_message`),`extend_bytes`=VALUES(`extend_bytes`) fn: "UpsertWorker", - inputs: []interface{}{ + inputs: []any{ &frameModel.WorkerStatus{ Model: model.Model{ CreatedAt: createdAt, @@ -743,7 +743,7 @@ func TestWorker(t *testing.T) { }, { fn: "UpsertWorker", - inputs: []interface{}{ + inputs: []any{ &frameModel.WorkerStatus{ Model: model.Model{ SeqID: 1, @@ -768,7 +768,7 @@ func TestWorker(t *testing.T) { }, { fn: "DeleteWorker", - inputs: []interface{}{ + inputs: []any{ "j111", "w222", }, @@ -781,7 +781,7 @@ func TestWorker(t *testing.T) { { // DELETE FROM `worker_statuses` WHERE project_id = '111-222-334' AND job_id = '111' AND worker_id = '222' fn: "DeleteWorker", - inputs: []interface{}{ + inputs: []any{ "j112", "w223", }, @@ -796,7 +796,7 @@ func TestWorker(t *testing.T) { { // 'UPDATE `worker_statuses` SET `epoch`=?,`error-message`=?,`extend-bytes`=?,`id`=?,`job_id`=?,`project_id`=?,`status`=?,`type`=?,`updated_at`=? WHERE job_id = ? && id = ?' fn: "UpdateWorker", - inputs: []interface{}{ + inputs: []any{ &frameModel.WorkerStatus{ ProjectID: "p111", JobID: "j111", @@ -816,7 +816,7 @@ func TestWorker(t *testing.T) { // SELECT * FROM `worker_statuses` WHERE project_id = '111-222-333' AND job_id = '111' AND // worker_id = '222' ORDER BY `worker_statuses`.`id` LIMIT 1 fn: "GetWorkerByID", - inputs: []interface{}{ + inputs: []any{ "j111", "w222", }, @@ -846,7 +846,7 @@ func TestWorker(t *testing.T) { }, { fn: "GetWorkerByID", - inputs: []interface{}{ + inputs: []any{ "j111", "w222", }, @@ -859,7 +859,7 @@ func TestWorker(t *testing.T) { { // SELECT * FROM `worker_statuses` WHERE project_id = '111-222-333' AND job_id = '111' fn: "QueryWorkersByMasterID", - inputs: []interface{}{ + inputs: []any{ "j111", }, output: []*frameModel.WorkerStatus{ @@ -890,7 +890,7 @@ func TestWorker(t *testing.T) { }, { fn: "QueryWorkersByMasterID", - inputs: []interface{}{ + inputs: []any{ "j111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -902,7 +902,7 @@ func TestWorker(t *testing.T) { { // SELECT * FROM `worker_statuses` WHERE project_id = '111-222-333' AND job_id = '111' AND worker_statuses = 1 fn: "QueryWorkersByState", - inputs: []interface{}{ + inputs: []any{ "j111", 1, }, @@ -934,7 +934,7 @@ func TestWorker(t *testing.T) { }, { fn: "QueryWorkersByState", - inputs: []interface{}{ + inputs: []any{ "j111", 1, }, @@ -968,7 +968,7 @@ func TestResource(t *testing.T) { testCases := []tCase{ { fn: "CreateResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ Model: model.Model{ SeqID: 1, @@ -999,7 +999,7 @@ func TestResource(t *testing.T) { }, { fn: "CreateResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ Model: model.Model{ SeqID: 1, @@ -1027,7 +1027,7 @@ func TestResource(t *testing.T) { }, { fn: "UpsertResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ Model: model.Model{ SeqID: 1, @@ -1048,7 +1048,7 @@ func TestResource(t *testing.T) { }, { fn: "UpsertResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ Model: model.Model{ SeqID: 1, @@ -1073,7 +1073,7 @@ func TestResource(t *testing.T) { }, { fn: "DeleteResource", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r222", @@ -1087,7 +1087,7 @@ func TestResource(t *testing.T) { }, { fn: "DeleteResource", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r223", @@ -1104,7 +1104,7 @@ func TestResource(t *testing.T) { { // 'UPDATE `resource_meta` SET `deleted`=?,`executor_id`=?,`id`=?,`job_id`=?,`project_id`=?,`worker_id`=?,`updated_at`=? WHERE id = ?' fn: "UpdateResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ ProjectID: "p111", ID: "w111", @@ -1120,7 +1120,7 @@ func TestResource(t *testing.T) { }, { fn: "GetResourceByID", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r222", @@ -1150,7 +1150,7 @@ func TestResource(t *testing.T) { }, { fn: "GetResourceByID", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r222", @@ -1164,7 +1164,7 @@ func TestResource(t *testing.T) { }, { fn: "QueryResourcesByJobID", - inputs: []interface{}{ + inputs: []any{ "j111", }, output: []*resModel.ResourceMeta{ @@ -1193,7 +1193,7 @@ func TestResource(t *testing.T) { }, { fn: "QueryResourcesByJobID", - inputs: []interface{}{ + inputs: []any{ "j111", }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -1204,7 +1204,7 @@ func TestResource(t *testing.T) { }, { fn: "QueryResourcesByExecutorIDs", - inputs: []interface{}{ + inputs: []any{ engineModel.ExecutorID("e444"), }, output: []*resModel.ResourceMeta{ @@ -1233,7 +1233,7 @@ func TestResource(t *testing.T) { }, { fn: "QueryResourcesByExecutorIDs", - inputs: []interface{}{ + inputs: []any{ engineModel.ExecutorID("e444"), engineModel.ExecutorID("e555"), }, @@ -1280,7 +1280,7 @@ func TestResource(t *testing.T) { }, { fn: "QueryResourcesByExecutorIDs", - inputs: []interface{}{ + inputs: []any{ engineModel.ExecutorID("e444"), }, err: errors.ErrMetaOpFail.GenWithStackByArgs(), @@ -1291,7 +1291,7 @@ func TestResource(t *testing.T) { }, { fn: "SetGCPendingByJobs", - inputs: []interface{}{ + inputs: []any{ "job-1", "job-2", "job-3", @@ -1310,7 +1310,7 @@ func TestResource(t *testing.T) { }, { fn: "DeleteResourcesByTypeAndExecutorIDs", - inputs: []interface{}{ + inputs: []any{ resModel.ResourceTypeLocalFile, engineModel.ExecutorID("executor-1"), }, @@ -1324,7 +1324,7 @@ func TestResource(t *testing.T) { }, { fn: "DeleteResourcesByTypeAndExecutorIDs", - inputs: []interface{}{ + inputs: []any{ resModel.ResourceTypeLocalFile, engineModel.ExecutorID("executor-1"), engineModel.ExecutorID("executor-2"), @@ -1445,7 +1445,7 @@ func TestJobOp(t *testing.T) { // SetJobCanceling successfully { fn: "SetJobCanceling", - inputs: []interface{}{ + inputs: []any{ "job-111", }, output: &ormResult{ @@ -1469,7 +1469,7 @@ func TestJobOp(t *testing.T) { // SetJobCanceling does nothing because cancelling op exists { fn: "SetJobCanceling", - inputs: []interface{}{ + inputs: []any{ "job-111", }, output: &ormResult{ @@ -1495,7 +1495,7 @@ func TestJobOp(t *testing.T) { // SetJobCanceling returns error if job is already cancelled { fn: "SetJobCanceling", - inputs: []interface{}{ + inputs: []any{ "job-111", }, output: &ormResult{ @@ -1522,7 +1522,7 @@ func TestJobOp(t *testing.T) { // SetJobCanceling updates job operation to canceling if exists a noop job operation { fn: "SetJobCanceling", - inputs: []interface{}{ + inputs: []any{ "job-111", }, output: &ormResult{ @@ -1549,7 +1549,7 @@ func TestJobOp(t *testing.T) { // SetJobCanceled { fn: "SetJobCanceled", - inputs: []interface{}{ + inputs: []any{ "job-111", }, output: &ormResult{ @@ -1565,7 +1565,7 @@ func TestJobOp(t *testing.T) { // QueryJobOp { fn: "QueryJobOp", - inputs: []interface{}{ + inputs: []any{ "job-1", }, output: &model.JobOp{ @@ -1588,7 +1588,7 @@ func TestJobOp(t *testing.T) { // QueryJobOpsByStatus { fn: "QueryJobOpsByStatus", - inputs: []interface{}{ + inputs: []any{ model.JobOpStatusCanceling, }, output: []*model.JobOp{ @@ -1649,7 +1649,7 @@ func TestExecutorClient(t *testing.T) { testCases := []tCase{ { fn: "CreateExecutor", - inputs: []interface{}{ + inputs: []any{ executor, }, output: &ormResult{ @@ -1663,7 +1663,7 @@ func TestExecutorClient(t *testing.T) { }, { fn: "UpdateExecutor", - inputs: []interface{}{ + inputs: []any{ executor, }, output: &ormResult{ @@ -1677,7 +1677,7 @@ func TestExecutorClient(t *testing.T) { }, { fn: "DeleteExecutor", - inputs: []interface{}{ + inputs: []any{ executor.ID, }, output: &ormResult{ @@ -1690,7 +1690,7 @@ func TestExecutorClient(t *testing.T) { }, { fn: "QueryExecutors", - inputs: []interface{}{}, + inputs: []any{}, output: []*model.Executor{executor}, mockExpectResFn: func(mock sqlmock.Sqlmock) { mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `executors`")). diff --git a/engine/pkg/orm/log.go b/engine/pkg/orm/log.go index 97044f2dca..a777072fc6 100644 --- a/engine/pkg/orm/log.go +++ b/engine/pkg/orm/log.go @@ -68,15 +68,15 @@ func (l *ormLogger) LogMode(logger.LogLevel) logger.Interface { return l } -func (l *ormLogger) Info(ctx context.Context, format string, args ...interface{}) { +func (l *ormLogger) Info(ctx context.Context, format string, args ...any) { l.lg.Info(fmt.Sprintf(format, args...)) } -func (l *ormLogger) Warn(ctx context.Context, format string, args ...interface{}) { +func (l *ormLogger) Warn(ctx context.Context, format string, args ...any) { l.lg.Warn(fmt.Sprintf(format, args...)) } -func (l *ormLogger) Error(ctx context.Context, format string, args ...interface{}) { +func (l *ormLogger) Error(ctx context.Context, format string, args ...any) { l.lg.Error(fmt.Sprintf(format, args...)) } diff --git a/engine/pkg/orm/mock_test.go b/engine/pkg/orm/mock_test.go index dae46531aa..ceaf7d6440 100644 --- a/engine/pkg/orm/mock_test.go +++ b/engine/pkg/orm/mock_test.go @@ -39,7 +39,7 @@ func TestGenEpochMock(t *testing.T) { defer cancel() var epoch int64 - for j := 0; j < 10; j++ { + for range 10 { epoch, err = mock.GenEpoch(ctx) require.NoError(t, err) } @@ -47,11 +47,11 @@ func TestGenEpochMock(t *testing.T) { } type mCase struct { - fn string // function name - inputs []interface{} // function args + fn string // function name + inputs []any // function args - output interface{} // function output - err error // function error + output any // function output + err error // function error } func TestInitializeMock(t *testing.T) { @@ -74,7 +74,7 @@ func TestProjectMock(t *testing.T) { testCases := []mCase{ { fn: "CreateProject", - inputs: []interface{}{ + inputs: []any{ &model.ProjectInfo{ Model: model.Model{ CreatedAt: createdAt, @@ -87,7 +87,7 @@ func TestProjectMock(t *testing.T) { }, { fn: "CreateProject", - inputs: []interface{}{ + inputs: []any{ &model.ProjectInfo{ Model: model.Model{ SeqID: 2, @@ -101,19 +101,19 @@ func TestProjectMock(t *testing.T) { }, { fn: "DeleteProject", - inputs: []interface{}{ + inputs: []any{ "p111", }, }, { fn: "DeleteProject", - inputs: []interface{}{ + inputs: []any{ "p114", }, }, { fn: "QueryProjects", - inputs: []interface{}{}, + inputs: []any{}, output: []*model.ProjectInfo{ { // FIXME: ?? @@ -132,7 +132,7 @@ func TestProjectMock(t *testing.T) { { // SELECT * FROM `project_infos` WHERE project_id = '111-222-333' ORDER BY `project_infos`.`id` LIMIT 1 fn: "GetProjectByID", - inputs: []interface{}{ + inputs: []any{ "p112", }, output: &model.ProjectInfo{ @@ -147,7 +147,7 @@ func TestProjectMock(t *testing.T) { }, { fn: "GetProjectByID", - inputs: []interface{}{ + inputs: []any{ "p113", }, err: errors.ErrMetaEntryNotFound.GenWithStackByArgs(), @@ -173,7 +173,7 @@ func TestProjectOperationMock(t *testing.T) { testCases := []mCase{ { fn: "CreateProjectOperation", - inputs: []interface{}{ + inputs: []any{ &model.ProjectOperation{ ProjectID: "p111", Operation: "Submit", @@ -184,7 +184,7 @@ func TestProjectOperationMock(t *testing.T) { }, { fn: "CreateProjectOperation", - inputs: []interface{}{ + inputs: []any{ &model.ProjectOperation{ ProjectID: "p111", Operation: "Pause", @@ -196,7 +196,7 @@ func TestProjectOperationMock(t *testing.T) { { // SELECT * FROM `project_operations` WHERE project_id = '111' fn: "QueryProjectOperations", - inputs: []interface{}{ + inputs: []any{ "p111", }, output: []*model.ProjectOperation{ @@ -219,7 +219,7 @@ func TestProjectOperationMock(t *testing.T) { { // SELECT * FROM `project_operations` WHERE project_id = '111' AND created_at >= '2022-04-13 23:51:42.46' AND created_at <= '2022-04-13 23:51:42.46' fn: "QueryProjectOperationsByTimeRange", - inputs: []interface{}{ + inputs: []any{ "p111", TimeRange{ start: tm2, @@ -256,7 +256,7 @@ func TestJobMock(t *testing.T) { testCases := []mCase{ { fn: "UpsertJob", - inputs: []interface{}{ + inputs: []any{ &frameModel.MasterMeta{ Model: model.Model{ CreatedAt: createdAt, @@ -275,7 +275,7 @@ func TestJobMock(t *testing.T) { }, { fn: "UpsertJob", - inputs: []interface{}{ + inputs: []any{ &frameModel.MasterMeta{ ProjectID: "p111", ID: "j111", @@ -289,7 +289,7 @@ func TestJobMock(t *testing.T) { }, { fn: "DeleteJob", - inputs: []interface{}{ + inputs: []any{ "j112", }, output: ormResult{ @@ -299,7 +299,7 @@ func TestJobMock(t *testing.T) { { // DELETE FROM `master_meta` WHERE project_id = '111-222-334' AND job_id = '111' fn: "DeleteJob", - inputs: []interface{}{ + inputs: []any{ "j113", }, output: ormResult{ @@ -309,7 +309,7 @@ func TestJobMock(t *testing.T) { { // SELECT * FROM `master_meta` WHERE project_id = '111-222-333' AND job_id = '111' ORDER BY `master_meta`.`id` LIMIT 1 fn: "GetJobByID", - inputs: []interface{}{ + inputs: []any{ "j111", }, output: &frameModel.MasterMeta{ @@ -330,7 +330,7 @@ func TestJobMock(t *testing.T) { }, { fn: "GetJobByID", - inputs: []interface{}{ + inputs: []any{ "j113", }, err: errors.ErrMetaEntryNotFound.GenWithStackByArgs(), @@ -338,7 +338,7 @@ func TestJobMock(t *testing.T) { { // SELECT * FROM `master_meta` WHERE project_id = '111-222-333' fn: "QueryJobsByProjectID", - inputs: []interface{}{ + inputs: []any{ "p111", }, output: []*frameModel.MasterMeta{ @@ -361,7 +361,7 @@ func TestJobMock(t *testing.T) { }, { fn: "QueryJobsByProjectID", - inputs: []interface{}{ + inputs: []any{ "p113", }, output: []*frameModel.MasterMeta{}, @@ -369,7 +369,7 @@ func TestJobMock(t *testing.T) { { // SELECT * FROM `master_meta` WHERE project_id = '111-222-333' AND job_status = 1 fn: "QueryJobsByState", - inputs: []interface{}{ + inputs: []any{ "j111", 2, }, @@ -393,7 +393,7 @@ func TestJobMock(t *testing.T) { }, { fn: "QueryJobsByState", - inputs: []interface{}{ + inputs: []any{ "j113", 1, }, @@ -422,7 +422,7 @@ func TestWorkerMock(t *testing.T) { // `worker_statuses`,`worker_err_msg`,`worker_config`,`id`) VALUES ('2022-04-14 11:35:06.119','2022-04-14 11:35:06.119', // '111-222-333','111','222',1,1,'error','',1) fn: "UpsertWorker", - inputs: []interface{}{ + inputs: []any{ &frameModel.WorkerStatus{ Model: model.Model{ CreatedAt: createdAt, @@ -440,7 +440,7 @@ func TestWorkerMock(t *testing.T) { }, { fn: "UpsertWorker", - inputs: []interface{}{ + inputs: []any{ &frameModel.WorkerStatus{ Model: model.Model{ CreatedAt: createdAt, @@ -458,7 +458,7 @@ func TestWorkerMock(t *testing.T) { }, { fn: "DeleteWorker", - inputs: []interface{}{ + inputs: []any{ "j111", "w223", }, @@ -469,7 +469,7 @@ func TestWorkerMock(t *testing.T) { { // DELETE FROM `worker_statuses` WHERE project_id = '111-222-334' AND job_id = '111' AND worker_id = '222' fn: "DeleteWorker", - inputs: []interface{}{ + inputs: []any{ "j112", "w224", }, @@ -481,7 +481,7 @@ func TestWorkerMock(t *testing.T) { // SELECT * FROM `worker_statuses` WHERE project_id = '111-222-333' AND job_id = '111' AND // worker_id = '222' ORDER BY `worker_statuses`.`id` LIMIT 1 fn: "GetWorkerByID", - inputs: []interface{}{ + inputs: []any{ "j111", "w222", }, @@ -502,7 +502,7 @@ func TestWorkerMock(t *testing.T) { }, { fn: "GetWorkerByID", - inputs: []interface{}{ + inputs: []any{ "j111", "w225", }, @@ -511,7 +511,7 @@ func TestWorkerMock(t *testing.T) { { // SELECT * FROM `worker_statuses` WHERE project_id = '111-222-333' AND job_id = '111' fn: "QueryWorkersByMasterID", - inputs: []interface{}{ + inputs: []any{ "j111", }, output: []*frameModel.WorkerStatus{ @@ -533,7 +533,7 @@ func TestWorkerMock(t *testing.T) { }, { fn: "QueryWorkersByMasterID", - inputs: []interface{}{ + inputs: []any{ "j113", }, output: []*frameModel.WorkerStatus{}, @@ -541,7 +541,7 @@ func TestWorkerMock(t *testing.T) { { // SELECT * FROM `worker_statuses` WHERE project_id = '111-222-333' AND job_id = '111' AND worker_statuses = 1 fn: "QueryWorkersByState", - inputs: []interface{}{ + inputs: []any{ "j111", 1, }, @@ -564,7 +564,7 @@ func TestWorkerMock(t *testing.T) { }, { fn: "QueryWorkersByState", - inputs: []interface{}{ + inputs: []any{ "j111", 4, }, @@ -590,7 +590,7 @@ func TestResourceMock(t *testing.T) { testCases := []mCase{ { fn: "UpsertResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ Model: model.Model{ CreatedAt: createdAt, @@ -607,7 +607,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "UpsertResource", - inputs: []interface{}{ + inputs: []any{ &resModel.ResourceMeta{ Model: model.Model{ CreatedAt: createdAt, @@ -624,7 +624,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "DeleteResource", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r334", @@ -636,7 +636,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "DeleteResource", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r335", @@ -648,7 +648,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "GetResourceByID", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r333", @@ -670,7 +670,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "GetResourceByID", - inputs: []interface{}{ + inputs: []any{ ResourceKey{ JobID: "j111", ID: "r335", @@ -680,7 +680,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "QueryResourcesByJobID", - inputs: []interface{}{ + inputs: []any{ "j111", }, output: []*resModel.ResourceMeta{ @@ -701,14 +701,14 @@ func TestResourceMock(t *testing.T) { }, { fn: "QueryResourcesByJobID", - inputs: []interface{}{ + inputs: []any{ "j112", }, output: []*resModel.ResourceMeta{}, }, { fn: "QueryResourcesByExecutorIDs", - inputs: []interface{}{ + inputs: []any{ engineModel.ExecutorID("e444"), }, output: []*resModel.ResourceMeta{ @@ -729,7 +729,7 @@ func TestResourceMock(t *testing.T) { }, { fn: "QueryResourcesByExecutorIDs", - inputs: []interface{}{ + inputs: []any{ engineModel.ExecutorID("e444"), }, output: []*resModel.ResourceMeta{}, diff --git a/engine/pkg/orm/model/common.go b/engine/pkg/orm/model/common.go index 8bd190e839..b4a82fd6cd 100644 --- a/engine/pkg/orm/model/common.go +++ b/engine/pkg/orm/model/common.go @@ -26,4 +26,4 @@ type Model struct { } // KeyValueMap alias to key value map when updating data in gorm -type KeyValueMap = map[string]interface{} +type KeyValueMap = map[string]any diff --git a/engine/pkg/orm/model/executor.go b/engine/pkg/orm/model/executor.go index f0c0f4c107..29b29e875c 100644 --- a/engine/pkg/orm/model/executor.go +++ b/engine/pkg/orm/model/executor.go @@ -42,7 +42,7 @@ func (s LabelSet) ToMap() map[string]string { } // Scan implements the sql.Scanner interface. -func (s *LabelSet) Scan(rawInput interface{}) error { +func (s *LabelSet) Scan(rawInput any) error { *s = make(LabelSet) if rawInput == nil { return nil @@ -88,8 +88,8 @@ type Executor struct { } // Map is used in gorm update. -func (e *Executor) Map() map[string]interface{} { - return map[string]interface{}{ +func (e *Executor) Map() map[string]any { + return map[string]any{ "id": e.ID, "name": e.Name, "address": e.Address, diff --git a/engine/pkg/orm/model/jobop.go b/engine/pkg/orm/model/jobop.go index 5b1f814b5d..8e3598122d 100644 --- a/engine/pkg/orm/model/jobop.go +++ b/engine/pkg/orm/model/jobop.go @@ -46,8 +46,8 @@ type JobOp struct { } // Map is used for update in orm model -func (op *JobOp) Map() map[string]interface{} { - return map[string]interface{}{ +func (op *JobOp) Map() map[string]any { + return map[string]any{ "op": op.Op, } } diff --git a/engine/pkg/p2p/message_sender.go b/engine/pkg/p2p/message_sender.go index 1d9eebbd4a..4b53a08472 100644 --- a/engine/pkg/p2p/message_sender.go +++ b/engine/pkg/p2p/message_sender.go @@ -28,10 +28,10 @@ type MessageSender interface { // SendToNode sends a message to a given node. Returns whether it is successful and a possible error. // A `would-block` error will not be returned. (false, nil) would be returned instead. - SendToNode(ctx context.Context, targetNodeID NodeID, topic Topic, message interface{}) (bool, error) + SendToNode(ctx context.Context, targetNodeID NodeID, topic Topic, message any) (bool, error) // SendToNodeB sends a message to a given node in a blocking way - SendToNodeB(ctx context.Context, targetNodeID NodeID, topic Topic, message interface{}) error + SendToNodeB(ctx context.Context, targetNodeID NodeID, topic Topic, message any) error } type messageSenderImpl struct { @@ -46,7 +46,7 @@ func NewMessageSender(router MessageRouter) MessageSender { // SendToNodeB implements MessageSender.SendToNodeB // Note the blocking send may have performance issue, BE CAUTION when using this function. func (m *messageSenderImpl) SendToNodeB( - ctx context.Context, targetNodeID NodeID, topic Topic, message interface{}, + ctx context.Context, targetNodeID NodeID, topic Topic, message any, ) error { client := m.router.GetClient(targetNodeID) if client == nil { @@ -58,7 +58,7 @@ func (m *messageSenderImpl) SendToNodeB( return err } -func (m *messageSenderImpl) SendToNode(ctx context.Context, targetNodeID NodeID, topic Topic, message interface{}) (bool, error) { +func (m *messageSenderImpl) SendToNode(ctx context.Context, targetNodeID NodeID, topic Topic, message any) (bool, error) { client := m.router.GetClient(targetNodeID) if client == nil { return false, nil diff --git a/engine/pkg/p2p/mock_message_handler_manager.go b/engine/pkg/p2p/mock_message_handler_manager.go index d78fb52f9e..3b3ddf8593 100644 --- a/engine/pkg/p2p/mock_message_handler_manager.go +++ b/engine/pkg/p2p/mock_message_handler_manager.go @@ -63,7 +63,7 @@ func (m *MockMessageHandlerManager) AssertNoHandler(t *testing.T, topic Topic) { // InvokeHandler gets the handler of given topic and invoke the handler to // simulate to send message from given sender -func (m *MockMessageHandlerManager) InvokeHandler(t *testing.T, topic Topic, senderID NodeID, message interface{}) error { +func (m *MockMessageHandlerManager) InvokeHandler(t *testing.T, topic Topic, senderID NodeID, message any) error { m.mu.RLock() defer m.mu.RUnlock() diff --git a/engine/pkg/p2p/mock_message_sender.go b/engine/pkg/p2p/mock_message_sender.go index c4c70dc051..64942bed52 100644 --- a/engine/pkg/p2p/mock_message_sender.go +++ b/engine/pkg/p2p/mock_message_sender.go @@ -50,7 +50,7 @@ func (m *MockMessageSender) SendToNodeB( ctx context.Context, targetNodeID NodeID, topic Topic, - message interface{}, + message any, ) error { m.mu.Lock() defer m.mu.Unlock() @@ -77,7 +77,7 @@ func (m *MockMessageSender) SendToNode( _ context.Context, targetNodeID NodeID, topic Topic, - message interface{}, + message any, ) (bool, error) { m.mu.Lock() defer m.mu.Unlock() @@ -104,7 +104,7 @@ func (m *MockMessageSender) SendToNode( } // TryPop tries to get a message from message sender -func (m *MockMessageSender) TryPop(targetNodeID NodeID, topic Topic) (interface{}, bool) { +func (m *MockMessageSender) TryPop(targetNodeID NodeID, topic Topic) (any, bool) { m.mu.Lock() defer m.mu.Unlock() diff --git a/engine/pkg/p2p/mock_message_sender_test.go b/engine/pkg/p2p/mock_message_sender_test.go index 4d714b0f2f..9c0902114e 100644 --- a/engine/pkg/p2p/mock_message_sender_test.go +++ b/engine/pkg/p2p/mock_message_sender_test.go @@ -33,11 +33,11 @@ func TestMockMessageSender(t *testing.T) { _, ok := sender.TryPop("dummy", "dummy") require.False(t, ok) - for i := 0; i < 50; i++ { + for i := range 50 { topicID := fmt.Sprintf("topic-%d", i) - for j := 0; j < 50; j++ { + for j := range 50 { nodeID := fmt.Sprintf("node-%d", j) - for k := 0; k < 50; k++ { + for k := range 50 { ok, err := sender.SendToNode(context.TODO(), nodeID, topicID, &msgForTesting{k}) require.True(t, ok) require.NoError(t, err) @@ -45,11 +45,11 @@ func TestMockMessageSender(t *testing.T) { } } - for i := 0; i < 50; i++ { + for i := range 50 { topicID := fmt.Sprintf("topic-%d", i) - for j := 0; j < 50; j++ { + for j := range 50 { nodeID := fmt.Sprintf("node-%d", j) - for k := 0; k < 50; k++ { + for k := range 50 { msg, ok := sender.TryPop(nodeID, topicID) require.True(t, ok) require.Equal(t, &msgForTesting{k}, msg) diff --git a/engine/pkg/p2p/server.go b/engine/pkg/p2p/server.go index 4b1c3ca01d..109c38a9c0 100644 --- a/engine/pkg/p2p/server.go +++ b/engine/pkg/p2p/server.go @@ -41,9 +41,9 @@ type ( type ( // TypeInformation is used to hold type data - TypeInformation = interface{} + TypeInformation = any // MessageValue is used to hold message object - MessageValue = interface{} + MessageValue = any // HandlerFunc alias to message handler function HandlerFunc = func(sender NodeID, value MessageValue) error ) diff --git a/engine/pkg/p2p/server_integration_test.go b/engine/pkg/p2p/server_integration_test.go index 67d4c2002c..a558ebf326 100644 --- a/engine/pkg/p2p/server_integration_test.go +++ b/engine/pkg/p2p/server_integration_test.go @@ -58,13 +58,11 @@ func TestMessageRPCServiceBasics(t *testing.T) { require.NoError(t, err) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := messageSrvc.Serve(ctx, l) require.Error(t, err) require.Regexp(t, ".*canceled.*", err.Error()) - }() + }) var called atomic.Bool handlerManager := messageSrvc.MakeHandlerManager() @@ -78,13 +76,11 @@ func TestMessageRPCServiceBasics(t *testing.T) { require.True(t, ok) client := p2pImpl.NewGrpcMessageClient("test-client-1", clientConfigForUnitTesting) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "tcp", addr, "test-node-1", &security.Credential{} /* no TLS */) require.Error(t, err) require.Regexp(t, ".*canceled.*", err.Error()) - }() + }) _, err = client.SendMessage(ctx, "test-topic-1", &msgContent{}) require.NoError(t, err) diff --git a/engine/pkg/rpcutil/middleware.go b/engine/pkg/rpcutil/middleware.go index 65513159d7..d375ba88f9 100644 --- a/engine/pkg/rpcutil/middleware.go +++ b/engine/pkg/rpcutil/middleware.go @@ -16,6 +16,7 @@ package rpcutil import ( "context" "reflect" + "slices" "strings" "time" @@ -208,10 +209,8 @@ func NormalizeError() grpc.UnaryServerInterceptor { // allowList is a list of methods that will be logged. limiter is used to limit the log rate. func Logger(allowList []string, limiter *rate.Limiter) grpc.UnaryServerInterceptor { allow := func(method string) bool { - for _, m := range allowList { - if m == method { - return true - } + if slices.Contains(allowList, method) { + return true } return limiter.Allow() } diff --git a/engine/servermaster/executor_manager.go b/engine/servermaster/executor_manager.go index 8da176b398..5a0dd26a4c 100644 --- a/engine/servermaster/executor_manager.go +++ b/engine/servermaster/executor_manager.go @@ -106,9 +106,7 @@ func (e *ExecutorManagerImpl) removeExecutorLocked(id model.ExecutorID) error { // // We use ttl mechanism to manage the executor's life cycle. So we can tolerate // that a tombstone executor may be left in the database. - e.wg.Add(1) - go func() { - defer e.wg.Done() + e.wg.Go(func() { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() @@ -116,7 +114,7 @@ func (e *ExecutorManagerImpl) removeExecutorLocked(id model.ExecutorID) error { if err := e.metaClient.DeleteExecutor(ctx, id); err != nil { log.Warn("failed to delete executor from database", zap.String("id", string(id)), zap.Error(err)) } - }() + }) return nil } diff --git a/engine/servermaster/executor_manager_test.go b/engine/servermaster/executor_manager_test.go index af8bbc3a1b..a0c6259fc4 100644 --- a/engine/servermaster/executor_manager_test.go +++ b/engine/servermaster/executor_manager_test.go @@ -79,11 +79,9 @@ func TestExecutorManager(t *testing.T) { metaClient.EXPECT().DeleteExecutor(gomock.Any(), executor.ID).Times(1).Return(nil) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { mgr.Run(ctx) - }() + }) require.Eventually(t, func() bool { return mgr.ExecutorCount(model.Running) == 0 @@ -170,9 +168,7 @@ func TestExecutorManagerWatch(t *testing.T) { require.NoError(t, err) ctxIn, cancelIn := context.WithCancel(ctx) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { ticker := time.NewTicker(time.Millisecond) defer ticker.Stop() for { @@ -184,7 +180,7 @@ func TestExecutorManagerWatch(t *testing.T) { require.NoError(t, err) } } - }() + }) return cancelIn } @@ -197,11 +193,9 @@ func TestExecutorManagerWatch(t *testing.T) { metaClient.EXPECT().DeleteExecutor(gomock.Any(), executorID2).Times(1).Return(nil) var mgrWg sync.WaitGroup - mgrWg.Add(1) - go func() { - defer mgrWg.Done() + mgrWg.Go(func() { mgr.Run(ctx) - }() + }) // mgr.Start will reset executors first, so there will be two online events. event = <-stream.C diff --git a/engine/servermaster/http_test.go b/engine/servermaster/http_test.go index 5ad2ba82b9..e6ec433ffb 100644 --- a/engine/servermaster/http_test.go +++ b/engine/servermaster/http_test.go @@ -120,7 +120,6 @@ func TestRegisterRoutes(t *testing.T) { } for i, tc := range testCases { - tc := tc t.Run(fmt.Sprintf("case-%d", i), func(t *testing.T) { t.Parallel() req := httptest.NewRequest(tc.method, tc.path, nil) @@ -182,7 +181,6 @@ func TestShouldForwardJobAPI(t *testing.T) { } for i, tc := range testCases { - tc := tc t.Run(fmt.Sprintf("case-%d", i), func(t *testing.T) { t.Parallel() req, err := http.NewRequestWithContext(ctx, tc.method, tc.path, nil) diff --git a/engine/servermaster/jobmanager.go b/engine/servermaster/jobmanager.go index e1e8e6c5a9..9792e71d07 100644 --- a/engine/servermaster/jobmanager.go +++ b/engine/servermaster/jobmanager.go @@ -757,7 +757,7 @@ func (jm *JobManagerImpl) OnWorkerOffline(worker framework.WorkerHandle, reason } // OnWorkerMessage implements frame.MasterImpl.OnWorkerMessage -func (jm *JobManagerImpl) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message interface{}) error { +func (jm *JobManagerImpl) OnWorkerMessage(worker framework.WorkerHandle, topic p2p.Topic, message any) error { log.Info("on worker message", zap.Any("id", worker.ID()), zap.Any("topic", topic), zap.Any("message", message)) return nil } diff --git a/engine/servermaster/jobmanager_test.go b/engine/servermaster/jobmanager_test.go index 45eecd8136..2679d3b1e8 100644 --- a/engine/servermaster/jobmanager_test.go +++ b/engine/servermaster/jobmanager_test.go @@ -68,8 +68,7 @@ func prepareMockJobManager( func TestJobManagerCreateJob(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterID := "create-job-test" mockMaster, mgr := prepareMockJobManager(ctx, t, masterID) @@ -109,7 +108,7 @@ func TestJobManagerCreateJob(t *testing.T) { // delete a finished job, re-create job with the same id will meet error err = mockMaster.GetFrameMetaClient().UpdateJob(ctx, job.Id, - map[string]interface{}{ + map[string]any{ "state": frameModel.MasterStateFinished, }, ) @@ -135,8 +134,7 @@ func (m *mockBaseMasterCreateWorkerFailed) CreateWorker( func TestCreateWorkerReturnError(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterImpl := framework.NewMockMasterImpl(t, "", "create-worker-with-error") framework.MockMasterPrepareMeta(ctx, t, masterImpl) @@ -166,8 +164,7 @@ func TestCreateWorkerReturnError(t *testing.T) { func TestJobManagerCancelJob(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterID := "cancel-job-test" mockMaster, mgr := prepareMockJobManager(ctx, t, masterID) @@ -195,7 +192,7 @@ func TestJobManagerCancelJob(t *testing.T) { require.NoError(t, err) require.Equal(t, pb.Job_Canceling, job.State) - for i := 0; i < 5; i++ { + for i := range 5 { err = mgr.jobOperator.Tick(ctx) require.NoError(t, err) require.Equal(t, i+1, mockWorkerHandle.SendMessageCount()) @@ -210,8 +207,7 @@ func TestJobManagerCancelJob(t *testing.T) { func TestJobManagerDeleteJob(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterID := "delete-job-test" mockMaster, mgr := prepareMockJobManager(ctx, t, masterID) @@ -238,8 +234,7 @@ func TestJobManagerDeleteJob(t *testing.T) { func TestJobManagerGetJob(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() testCases := []struct { meta *frameModel.MasterMeta @@ -316,8 +311,7 @@ func TestJobManagerGetJob(t *testing.T) { func TestJobManagerOnlineJob(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockMaster := framework.NewMockMasterImpl(t, "", "submit-job-test") framework.MockMasterPrepareMeta(ctx, t, mockMaster) @@ -356,8 +350,7 @@ func TestJobManagerOnlineJob(t *testing.T) { func TestJobManagerRecover(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockMaster := framework.NewMockMasterImpl(t, "", "job-manager-recover-test") framework.MockMasterPrepareMeta(ctx, t, mockMaster) @@ -394,8 +387,7 @@ func TestJobManagerRecover(t *testing.T) { func TestJobManagerTickExceedQuota(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterImpl := framework.NewMockMasterImpl(t, "", "create-worker-with-error") framework.MockMasterPrepareMeta(ctx, t, masterImpl) @@ -428,8 +420,7 @@ func TestJobManagerTickExceedQuota(t *testing.T) { func TestJobManagerWatchJobStatuses(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterID := "delete-job-test" mockMaster, mgr := prepareMockJobManager(ctx, t, masterID) @@ -544,8 +535,7 @@ func TestGetJobDetailFromJobMaster(t *testing.T) { func TestListJobsPagination(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockMaster := framework.NewMockMasterImpl(t, "", "job-manager-list-jobs-test") masterMeta := mockMaster.DefaultBaseMaster.MasterMeta() @@ -556,7 +546,7 @@ func TestListJobsPagination(t *testing.T) { const totalJobCount = 2000 jobIDs := make([]string, 0, totalJobCount) - for i := 0; i < totalJobCount; i++ { + for i := range totalJobCount { jobID := fmt.Sprintf("job-%04d", i) jobIDs = append(jobIDs, jobID) cli := metadata.NewMasterMetadataClient(jobID, mockMaster.GetFrameMetaClient()) @@ -580,7 +570,7 @@ func TestListJobsPagination(t *testing.T) { resp, err := mgr.ListJobs(ctx, &pb.ListJobsRequest{}) require.NoError(t, err) require.Len(t, resp.Jobs, defaultListPageSize) - for i := 0; i < defaultListPageSize; i++ { + for i := range defaultListPageSize { require.Equal(t, jobIDs[i], resp.Jobs[i].Id) } require.Equal(t, jobIDs[defaultListPageSize-1], resp.NextPageToken) @@ -613,8 +603,7 @@ func TestListJobsPagination(t *testing.T) { func TestListJobWithFilter(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockMaster := framework.NewMockMasterImpl(t, "", "job-manager-list-jobs-test") masterMeta := mockMaster.DefaultBaseMaster.MasterMeta() @@ -641,7 +630,7 @@ func TestListJobWithFilter(t *testing.T) { const totalJobCount = maxListPageSize countByType := make(map[frameModel.WorkerType]int) countByState := make(map[frameModel.MasterState]int) - for i := 0; i < totalJobCount; i++ { + for i := range totalJobCount { jobID := fmt.Sprintf("job-%04d", i) cli := metadata.NewMasterMetadataClient("job-1", mockMaster.GetFrameMetaClient()) masterMeta := &frameModel.MasterMeta{ @@ -684,8 +673,7 @@ func TestListJobWithFilter(t *testing.T) { func TestOnWorkerDispatchedFastFail(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterID := "job-fast-fail-test" mockMaster, mgr := prepareMockJobManager(ctx, t, masterID) @@ -710,8 +698,7 @@ func TestOnWorkerDispatchedFastFail(t *testing.T) { func TestJobOperatorBgLoop(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterID := "job-operator-bg-loop-test" mockMaster, mgr := prepareMockJobManager(ctx, t, masterID) @@ -732,7 +719,7 @@ func TestJobOperatorBgLoop(t *testing.T) { return nil }) wg.Go(func() error { - for i := 0; i < 6; i++ { + for range 6 { mgr.jobOperatorNotifier.Notify() time.Sleep(time.Millisecond * 50) } @@ -763,8 +750,7 @@ func dispatchJobAndMeetError( func TestJobManagerIterPendingJobs(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() masterImpl := framework.NewMockMasterImpl(t, "", "iter-pending-jobs-test") framework.MockMasterPrepareMeta(ctx, t, masterImpl) @@ -832,8 +818,7 @@ func TestJobManagerIterPendingJobs(t *testing.T) { func TestFailoverWithCreateWorkerOpt(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() selectors := []*label.Selector{ {Key: "name", Target: "executor.*", Op: label.OpRegex}, diff --git a/engine/servermaster/jobop/backoff_test.go b/engine/servermaster/jobop/backoff_test.go index 4082864300..c3d0f8a90a 100644 --- a/engine/servermaster/jobop/backoff_test.go +++ b/engine/servermaster/jobop/backoff_test.go @@ -45,7 +45,7 @@ func TestJobBackoff(t *testing.T) { require.True(t, bkf.Allow()) // simulate consecutive failures - for i := 0; i < 10; i++ { + for range 10 { bkf.Fail() } require.False(t, bkf.Allow()) diff --git a/engine/servermaster/jobop/operator_test.go b/engine/servermaster/jobop/operator_test.go index e1660c6b24..daa3f61001 100644 --- a/engine/servermaster/jobop/operator_test.go +++ b/engine/servermaster/jobop/operator_test.go @@ -101,7 +101,7 @@ func TestJobOperator(t *testing.T) { err = oper.MarkJobCanceling(ctx, jobID) require.NoError(t, err) - for i := 0; i < 3; i++ { + for i := range 3 { err = oper.Tick(ctx) require.NoError(t, err) router.checkCancelCalls(t, jobID, i+1) diff --git a/engine/servermaster/server_test.go b/engine/servermaster/server_test.go index f73a22665e..434f506019 100644 --- a/engine/servermaster/server_test.go +++ b/engine/servermaster/server_test.go @@ -94,11 +94,9 @@ func TestServe(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = s.serve(ctx) - }() + }) require.Eventually(t, func() bool { conn, err := net.Dial("tcp", cfg.Addr) @@ -204,11 +202,9 @@ func TestCollectMetric(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = s.serve(ctx) - }() + }) jobManager := &mockJobManager{ jobs: map[pb.Job_State][]*pb.Job{ @@ -284,11 +280,9 @@ func TestHTTPErrorHandler(t *testing.T) { defer cancel() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = s.serve(ctx) - }() + }) require.Eventually(t, func() bool { conn, err := net.Dial("tcp", cfg.Addr) diff --git a/engine/servermaster/serverutil/watch_executors_test.go b/engine/servermaster/serverutil/watch_executors_test.go index 8b1305f985..2bd7adf15a 100644 --- a/engine/servermaster/serverutil/watch_executors_test.go +++ b/engine/servermaster/serverutil/watch_executors_test.go @@ -128,13 +128,11 @@ func TestWatchExecutors(t *testing.T) { } var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := WatchExecutors(ctx, watcher, user) require.ErrorIs(t, err, context.Canceled) - }() + }) for _, event := range events { evNotifier.Notify(event) @@ -187,12 +185,10 @@ func TestCloseWatchExecutors(t *testing.T) { user.On("UpdateExecutorList", snap).Return(nil).Times(1) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := WatchExecutors(ctx, watcher, user) require.ErrorIs(t, err, errors.ErrExecutorWatcherClosed) - }() + }) evNotifier.Close() wg.Wait() diff --git a/engine/servermaster/service_util_test.go b/engine/servermaster/service_util_test.go index 2b6e3249e9..5b267d960a 100644 --- a/engine/servermaster/service_util_test.go +++ b/engine/servermaster/service_util_test.go @@ -30,7 +30,7 @@ func TestGenerateNodeID(t *testing.T) { ) ids := make(map[string]struct{}) - for i := 0; i < genCount; i++ { + for range genCount { id := generateNodeID(name) require.True(t, strings.HasPrefix(id, name+"-")) ids[id] = struct{}{} diff --git a/engine/test/e2e/e2e_dm_test.go b/engine/test/e2e/e2e_dm_test.go index ffcf3e1aa2..6cbc2f3eba 100644 --- a/engine/test/e2e/e2e_dm_test.go +++ b/engine/test/e2e/e2e_dm_test.go @@ -211,7 +211,7 @@ func testSimpleAllModeTask( db string, ) { ctx := context.Background() - noError := func(_ interface{}, err error) { + noError := func(_ any, err error) { require.NoError(t, err) } @@ -427,7 +427,7 @@ func testSimpleAllModeTask( // update with new balist newDB := "new_" + db - dmJobCfg = bytes.ReplaceAll(dmJobCfg, []byte(fmt.Sprintf(`["%s"]`, db)), []byte(fmt.Sprintf(`["%s", "%s"]`, db, newDB))) + dmJobCfg = bytes.ReplaceAll(dmJobCfg, fmt.Appendf(nil, `["%s"]`, db), fmt.Appendf(nil, `["%s", "%s"]`, db, newDB)) err = updateJobCfg(ctx, httpClient, jobID, string(dmJobCfg)) require.NoError(t, err) // get new config @@ -465,7 +465,7 @@ func testSimpleDumpSyncModeTask( db string, ) { ctx := context.Background() - noError := func(_ interface{}, err error) { + noError := func(_ any, err error) { require.NoError(t, err) } @@ -495,7 +495,7 @@ func testSimpleDumpSyncModeTask( secretAccessKey := os.Getenv(envS3SecretAccessKey) require.Greater(t, len(secretAccessKey), 0, "empty secret access key in env %s", envS3SecretAccessKey) - dmJobCfg = bytes.ReplaceAll(dmJobCfg, []byte("# dir: ./dumped_data"), []byte(fmt.Sprintf(" dir: s3://engine-it/dumped_data_%s?force-path-style=1&access-key=%s&secret-access-key=%s&endpoint=%s", db, accessKeyID, secretAccessKey, endpoint))) + dmJobCfg = bytes.ReplaceAll(dmJobCfg, []byte("# dir: ./dumped_data"), fmt.Appendf(nil, " dir: s3://engine-it/dumped_data_%s?force-path-style=1&access-key=%s&secret-access-key=%s&endpoint=%s", db, accessKeyID, secretAccessKey, endpoint)) var jobID string require.Eventually(t, func() bool { var err error @@ -695,7 +695,7 @@ func testSimpleDumpSyncModeTask( // update with new balist newDB := "new_" + db - dmJobCfg = bytes.ReplaceAll(dmJobCfg, []byte(fmt.Sprintf(`["%s"]`, db)), []byte(fmt.Sprintf(`["%s", "%s"]`, db, newDB))) + dmJobCfg = bytes.ReplaceAll(dmJobCfg, fmt.Appendf(nil, `["%s"]`, db), fmt.Appendf(nil, `["%s", "%s"]`, db, newDB)) err = updateJobCfg(ctx, httpClient, jobID, string(dmJobCfg)) require.NoError(t, err) // get new config diff --git a/engine/test/e2e/e2e_node_chaos_test.go b/engine/test/e2e/e2e_node_chaos_test.go index 8824064fc1..44f1f3cc8e 100644 --- a/engine/test/e2e/e2e_node_chaos_test.go +++ b/engine/test/e2e/e2e_node_chaos_test.go @@ -42,7 +42,7 @@ func updateKeyAndCheckOnce( zap.Int("expect-mvcc", expectedMvcc)) ctx1, cancel := context.WithTimeout(ctx, DefaultTimeoutForTest) defer cancel() - for j := 0; j < workerCount; j++ { + for j := range workerCount { err := cli.UpdateFakeJobKey(ctx1, j, updateValue) require.NoError(t, err) } @@ -51,7 +51,7 @@ func updateKeyAndCheckOnce( ctx1, cancel := context.WithTimeout(ctx, DefaultTimeoutForTest) defer cancel() log.Debug("wait and check fake job value and mvcc. tick.") - for jobIdx := 0; jobIdx < workerCount; jobIdx++ { + for jobIdx := range workerCount { err := cli.CheckFakeJobKey(ctx1, jobID, jobIdx, expectedMvcc, updateValue) if err != nil { log.Warn("check fake job failed", zap.Error(err)) @@ -135,7 +135,7 @@ func TestNodeFailure(t *testing.T) { updateKeyAndCheckOnce(ctx, t, cli, jobID, cfg.WorkerCount, "random-value-1", mvccCount) log.Info("restart all server masters and check fake job is running normally") - for i := 0; i < nodeCount; i++ { + for i := range nodeCount { cli.ContainerRestart(masterContainerName(i)) mvccCount++ value := fmt.Sprintf("restart-server-master-value-%d", i) @@ -157,18 +157,18 @@ func TestNodeFailure(t *testing.T) { }, time.Second*10, time.Second, "leader is not changed") log.Info("restart all executors and check fake job is running normally") - for i := 0; i < nodeCount; i++ { + for i := range nodeCount { cli.ContainerRestart(executorContainerName(i)) mvccCount++ value := fmt.Sprintf("restart-executor-value-%d", i) updateKeyAndCheckOnce(ctx, t, cli, jobID, cfg.WorkerCount, value, mvccCount) } - for i := 0; i < nodeCount; i++ { + for i := range nodeCount { cli.ContainerStop(masterContainerName(i)) cli.ContainerStop(executorContainerName(i)) } - for i := 0; i < nodeCount; i++ { + for i := range nodeCount { cli.ContainerStart(masterContainerName(i)) cli.ContainerStart(executorContainerName(i)) } diff --git a/engine/test/mock/grpc.go b/engine/test/mock/grpc.go index 8a3e17266f..a0f84d847e 100644 --- a/engine/test/mock/grpc.go +++ b/engine/test/mock/grpc.go @@ -64,7 +64,7 @@ func (s *masterServerConn) Close() error { return nil } -func (s *masterServerConn) sendRequest(ctx context.Context, req interface{}) (interface{}, error) { +func (s *masterServerConn) sendRequest(ctx context.Context, req any) (any, error) { switch x := req.(type) { case *pb.RegisterExecutorRequest: return s.server.RegisterExecutor(ctx, x) @@ -127,7 +127,7 @@ func NewExecutorClient(conn Conn) pb.ExecutorServiceClient { return &executorClient{conn} } -func (s *executorServerConn) sendRequest(ctx context.Context, req interface{}) (interface{}, error) { +func (s *executorServerConn) sendRequest(ctx context.Context, req any) (any, error) { switch x := req.(type) { case *pb.PreDispatchTaskRequest: return s.server.PreDispatchTask(ctx, x) @@ -180,7 +180,7 @@ func NewExecutorServer(addr string, server pb.ExecutorServiceServer) (GrpcServer // Conn is a simple interface that support send gRPC requests and closeable type Conn interface { Close() error - sendRequest(ctx context.Context, req interface{}) (interface{}, error) + sendRequest(ctx context.Context, req any) (any, error) } // ResetGrpcCtx resets grpc servers diff --git a/engine/test/mock/test_server.go b/engine/test/mock/test_server.go index c918d9a738..bffbed0de1 100644 --- a/engine/test/mock/test_server.go +++ b/engine/test/mock/test_server.go @@ -97,11 +97,11 @@ func (s *testStream) SetTrailer(metadata.MD) {} func (s *testStream) Context() context.Context { return nil } -func (s *testStream) SendMsg(interface{}) error { +func (s *testStream) SendMsg(any) error { return errors.New("unimplemented") } -func (s *testStream) RecvMsg(interface{}) error { +func (s *testStream) RecvMsg(any) error { return errors.New("unimplemented") } @@ -115,7 +115,7 @@ func (s *testStream) CloseSend() error { return errors.New("unimplemented") } -func (s *testServerConn) sendRequest(ctx context.Context, req interface{}) (interface{}, error) { +func (s *testServerConn) sendRequest(ctx context.Context, req any) (any, error) { switch x := req.(type) { case *pb.TestBinlogRequest: stream := &testStream{ diff --git a/pkg/api/internal/rest/request.go b/pkg/api/internal/rest/request.go index 4fa31e0856..cbbec9ba6b 100644 --- a/pkg/api/internal/rest/request.go +++ b/pkg/api/internal/rest/request.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "io" + "maps" "net/http" "net/url" "path" @@ -129,9 +130,7 @@ func (r *Request) WithURI(uri string) *Request { if r.params == nil { r.params = make(url.Values) } - for k, v := range vals { - r.params[k] = v - } + maps.Copy(r.params, vals) } return r } @@ -210,7 +209,7 @@ func (r *Request) WithMaxRetries(maxRetries uint64) *Request { // only supports two types now: // 1. io.Reader // 2. type which can be json marshalled -func (r *Request) WithBody(obj interface{}) *Request { +func (r *Request) WithBody(obj any) *Request { if r.err != nil { return r } @@ -406,7 +405,7 @@ func (r Result) Error() error { } // Into stores the http response body into obj. -func (r Result) Into(obj interface{}) error { +func (r Result) Into(obj any) error { if r.err != nil { return r.err } diff --git a/pkg/api/internal/rest/request_test.go b/pkg/api/internal/rest/request_test.go index be0f4d19a7..5684cbd224 100644 --- a/pkg/api/internal/rest/request_test.go +++ b/pkg/api/internal/rest/request_test.go @@ -128,8 +128,7 @@ func TestRequestDoContextTimeout(t *testing.T) { })) defer testServer.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() c, err := CDCRESTClientFromConfig(&Config{ Host: testServer.URL, diff --git a/pkg/applier/redo_test.go b/pkg/applier/redo_test.go index 6b67e57e65..fcde318266 100644 --- a/pkg/applier/redo_test.go +++ b/pkg/applier/redo_test.go @@ -89,8 +89,7 @@ func (br *MockReader) ReadMeta(ctx context.Context) (checkpointTs, resolvedTs ui } func TestApply(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() checkpointTs := uint64(1000) resolvedTs := uint64(2000) @@ -303,8 +302,7 @@ func TestApply(t *testing.T) { } func TestApplyBigTxn(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() checkpointTs := uint64(1000) resolvedTs := uint64(2000) @@ -479,8 +477,7 @@ func TestApplyBigTxn(t *testing.T) { } func TestApplyMeetSinkError(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() port, err := freeport.GetFreePort() require.Nil(t, err) diff --git a/pkg/causality/conflict_detector.go b/pkg/causality/conflict_detector.go index 417fda4f21..5dc269354e 100644 --- a/pkg/causality/conflict_detector.go +++ b/pkg/causality/conflict_detector.go @@ -61,11 +61,9 @@ func NewConflictDetector[Txn txnEvent]( ret.resolvedTxnCaches[i] = newTxnCache[Txn](opt) } - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { ret.runBackgroundTasks() - }() + }) return ret } diff --git a/pkg/causality/internal/slots.go b/pkg/causality/internal/slots.go index 99e32ca429..15c2dabb2b 100644 --- a/pkg/causality/internal/slots.go +++ b/pkg/causality/internal/slots.go @@ -35,7 +35,7 @@ type Slots struct { // NewSlots creates a new Slots. func NewSlots(numSlots uint64) *Slots { slots := make([]slot, numSlots) - for i := uint64(0); i < numSlots; i++ { + for i := range numSlots { slots[i].nodes = make(map[uint64]*Node, 8) } return &Slots{ diff --git a/pkg/causality/internal/slots_test.go b/pkg/causality/internal/slots_test.go index 312523355a..e508b06d7b 100644 --- a/pkg/causality/internal/slots_test.go +++ b/pkg/causality/internal/slots_test.go @@ -29,13 +29,13 @@ func TestSlotsTrivial(t *testing.T) { slots := NewSlots(8) nodes := make([]*Node, 0, 1000) - for i := 0; i < count; i++ { + for range count { node := newNodeForTest(1, 2, 3, 4, 5) slots.Add(node) nodes = append(nodes, node) } - for i := 0; i < count; i++ { + for i := range count { slots.Remove(nodes[i]) } @@ -53,7 +53,7 @@ func TestSlotsConcurrentOps(t *testing.T) { slots := NewSlots(8) freeNodeChan := make(chan *Node, N) inuseNodeChan := make(chan *Node, N) - for i := 0; i < N; i++ { + for range N { freeNodeChan <- newNodeForTest(1, 9, 17, 25, 33) } @@ -62,9 +62,7 @@ func TestSlotsConcurrentOps(t *testing.T) { // test concurrent add and remove won't panic var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { select { case <-ctx.Done(): @@ -75,11 +73,9 @@ func TestSlotsConcurrentOps(t *testing.T) { inuseNodeChan <- node } } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { select { case <-ctx.Done(): @@ -90,7 +86,7 @@ func TestSlotsConcurrentOps(t *testing.T) { freeNodeChan <- newNodeForTest(1, 9, 17, 25, 33) } } - }() + }) wg.Wait() } diff --git a/pkg/causality/tests/driver.go b/pkg/causality/tests/driver.go index bac3aa50c4..c06d02397e 100644 --- a/pkg/causality/tests/driver.go +++ b/pkg/causality/tests/driver.go @@ -43,7 +43,7 @@ func newConflictTestDriver( }) workers := make([]*workerForTest, 0, numWorkers) - for i := 0; i < numWorkers; i++ { + for i := range numWorkers { id := int64(i) workers = append(workers, newWorkerForTest(detector.GetOutChByCacheID(id))) } diff --git a/pkg/causality/tests/worker.go b/pkg/causality/tests/worker.go index 363fce7526..ba4aa84740 100644 --- a/pkg/causality/tests/worker.go +++ b/pkg/causality/tests/worker.go @@ -55,11 +55,9 @@ func newWorkerForTest(txnCh <-chan causality.TxnWithNotifier[*txnForTest]) *work closeCh: make(chan struct{}), } - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { ret.run(txnCh) - }() + }) return ret } diff --git a/pkg/causality/txn_cache_test.go b/pkg/causality/txn_cache_test.go index d83a937c5c..b3bdff1801 100644 --- a/pkg/causality/txn_cache_test.go +++ b/pkg/causality/txn_cache_test.go @@ -38,7 +38,7 @@ func TestBoundedWorker(t *testing.T) { Size: size, BlockStrategy: BlockStrategyWaitAvailable, }) - for i := 0; i < size; i++ { + for range size { // Add 10 events to the worker. ok := worker.add(TxnWithNotifier[txnEvent]{ TxnEvent: mockTxnEvent{}, @@ -66,7 +66,7 @@ func TestBoundedWorkerWithBlock(t *testing.T) { Size: size, BlockStrategy: BlockStrategyWaitEmpty, }) - for i := 0; i < size; i++ { + for range size { // Add 10 events to the worker. ok := worker.add(TxnWithNotifier[txnEvent]{ TxnEvent: mockTxnEvent{}, diff --git a/pkg/chann/chann_test.go b/pkg/chann/chann_test.go index 7b56f7e869..c7151ce9df 100644 --- a/pkg/chann/chann_test.go +++ b/pkg/chann/chann_test.go @@ -131,22 +131,22 @@ func TestChan(t *testing.T) { // ensure that we receive them non-corrupted in FIFO order. c := New[int](Cap(chanCap)) go func() { - for i := 0; i < 100; i++ { + for i := range 100 { c.In() <- i } }() - for i := 0; i < 100; i++ { + for i := range 100 { v := <-c.Out() require.Equalf(t, i, v, "chan[%d]", chanCap) } // Same, but using recv2. go func() { - for i := 0; i < 100; i++ { + for i := range 100 { c.In() <- i } }() - for i := 0; i < 100; i++ { + for i := range 100 { v, ok := <-c.Out() require.Truef(t, ok, "chan[%d]: receive failed, expected %v", chanCap, i) require.Equalf(t, i, v, "chan[%d]", chanCap) @@ -156,18 +156,18 @@ func TestChan(t *testing.T) { // ensure that we receive what we send. const P = 4 const L = 1000 - for p := 0; p < P; p++ { + for range P { go func() { - for i := 0; i < L; i++ { + for i := range L { c.In() <- i } }() } done := New[map[int]int](Cap(0)) - for p := 0; p < P; p++ { + for range P { go func() { recv := make(map[int]int) - for i := 0; i < L; i++ { + for range L { v := <-c.Out() recv[v] = recv[v] + 1 } @@ -175,7 +175,7 @@ func TestChan(t *testing.T) { }() } recv := make(map[int]int) - for p := 0; p < P; p++ { + for range P { for k, v := range <-done.Out() { recv[k] = recv[k] + v } @@ -242,7 +242,7 @@ const internalCacheSize = 16 + 1<<10 func TestNonblockSelectRace(t *testing.T) { n := 1000 done := New[bool](Cap(1)) - for i := 0; i < n; i++ { + for range n { c1 := New[int]() c2 := New[int]() // The input channel of an unbounded buffer have an internal @@ -250,7 +250,7 @@ func TestNonblockSelectRace(t *testing.T) { // queue both gets full, we are certain that once the next send // is complete, the out will be available for sure hence the // waiting time of a receive is bounded. - for i := 0; i < internalCacheSize; i++ { + for range internalCacheSize { c1.In() <- 1 } c1.In() <- 1 @@ -266,7 +266,7 @@ func TestNonblockSelectRace(t *testing.T) { done.In() <- true }() // Same for c2 - for i := 0; i < internalCacheSize; i++ { + for range internalCacheSize { c2.In() <- 1 } c2.In() <- 1 @@ -289,11 +289,11 @@ func TestNonblockSelectRace(t *testing.T) { func TestNonblockSelectRace2(t *testing.T) { n := 1000 done := make(chan bool, 1) - for i := 0; i < n; i++ { + for range n { c1 := New[int]() c2 := New[int]() // See TestNonblockSelectRace. - for i := 0; i < internalCacheSize; i++ { + for range internalCacheSize { c1.In() <- 1 } c1.In() <- 1 @@ -331,17 +331,15 @@ func TestUnboundedChann(t *testing.T) { t.Run("interface{}", func(t *testing.T) { t.Run("send", func(t *testing.T) { // Ensure send to an unbounded channel does not block. - c := New[interface{}]() + c := New[any]() blocked := false - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case c.In() <- true: default: blocked = true } - }() + }) wg.Wait() require.Falsef(t, blocked, "send op to an unbounded channel blocked") c.Close() @@ -350,23 +348,21 @@ func TestUnboundedChann(t *testing.T) { t.Run("recv", func(t *testing.T) { // Ensure that receive op from unbounded chan can happen on // the same goroutine of send op. - c := New[interface{}]() - wg.Add(1) - go func() { - defer wg.Done() + c := New[any]() + wg.Go(func() { c.In() <- true <-c.Out() - }() + }) wg.Wait() c.Close() }) t.Run("order", func(t *testing.T) { // Ensure that the unbounded channel processes everything FIFO. - c := New[interface{}]() - for i := 0; i < 1<<11; i++ { + c := New[any]() + for i := range 1 << 11 { c.In() <- i } - for i := 0; i < 1<<11; i++ { + for i := range 1 << 11 { val := <-c.Out() require.Equalf( t, @@ -383,15 +379,13 @@ func TestUnboundedChann(t *testing.T) { // Ensure send to an unbounded channel does not block. c := New[struct{}]() blocked := false - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case c.In() <- struct{}{}: default: blocked = true } - }() + }) <-c.Out() wg.Wait() require.Falsef(t, blocked, "send op to an unbounded channel blocked") @@ -402,23 +396,21 @@ func TestUnboundedChann(t *testing.T) { // Ensure that receive op from unbounded chan can happen on // the same goroutine of send op. c := New[struct{}]() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { c.In() <- struct{}{} <-c.Out() - }() + }) wg.Wait() c.Close() }) t.Run("order", func(t *testing.T) { // Ensure that the unbounded channel processes everything FIFO. c := New[struct{}]() - for i := 0; i < 1<<11; i++ { + for range 1 << 11 { c.In() <- struct{}{} } n := 0 - for i := 0; i < 1<<11; i++ { + for range 1 << 11 { if _, ok := <-c.Out(); ok { n++ } @@ -433,7 +425,7 @@ func TestUnboundedChann(t *testing.T) { func TestUnboundedChannClose(t *testing.T) { t.Run("close-status", func(t *testing.T) { ch := New[any]() - for i := 0; i < 100; i++ { + for range 100 { ch.In() <- 0 } ch.Close() @@ -455,7 +447,7 @@ func TestUnboundedChannClose(t *testing.T) { n := 0 done := make(chan struct{}) ch := New[struct{}]() - for i := 0; i < N; i++ { + for range N { ch.In() <- struct{}{} } go func() { @@ -476,8 +468,8 @@ func TestUnboundedChannClose(t *testing.T) { N := 10 n := 0 done := make(chan struct{}) - ch := New[interface{}]() - for i := 0; i < N; i++ { + ch := New[any]() + for range N { ch.In() <- true } go func() { @@ -497,7 +489,7 @@ func TestUnboundedChannClose(t *testing.T) { func BenchmarkUnboundedChann(b *testing.B) { b.Run("interface{}", func(b *testing.B) { b.Run("sync", func(b *testing.B) { - c := New[interface{}]() + c := New[any]() defer c.Close() b.ResetTimer() b.ReportAllocs() @@ -507,7 +499,7 @@ func BenchmarkUnboundedChann(b *testing.B) { } }) b.Run("chann", func(b *testing.B) { - c := New[interface{}]() + c := New[any]() defer c.Close() b.ResetTimer() b.ReportAllocs() diff --git a/pkg/chann/drainable_chann_test.go b/pkg/chann/drainable_chann_test.go index e4dcd4b7e9..49490bece8 100644 --- a/pkg/chann/drainable_chann_test.go +++ b/pkg/chann/drainable_chann_test.go @@ -17,7 +17,7 @@ import "testing" func TestCloseAndDrain(t *testing.T) { ch := NewAutoDrainChann[int]() - for i := 0; i < 100; i++ { + for i := range 100 { ch.In() <- i } diff --git a/pkg/chdelay/channel_delayer_test.go b/pkg/chdelay/channel_delayer_test.go index 8433abbdf8..9d657d5ba8 100644 --- a/pkg/chdelay/channel_delayer_test.go +++ b/pkg/chdelay/channel_delayer_test.go @@ -38,19 +38,15 @@ func testChannelDelayer(t *testing.T, delayBy time.Duration, count int) { delayer := NewChannelDelayer(delayBy, inCh, 1024, 16) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer close(inCh) - for i := 0; i < count; i++ { + for range count { inCh <- time.Now() } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { counter := 0 for ts := range delayer.Out() { @@ -59,7 +55,7 @@ func testChannelDelayer(t *testing.T, delayBy time.Duration, count int) { } require.Equal(t, count, counter) - }() + }) wg.Wait() delayer.Close() diff --git a/pkg/cmd/factory/factory_impl_test.go b/pkg/cmd/factory/factory_impl_test.go index 4f33e673c1..e2275ae695 100644 --- a/pkg/cmd/factory/factory_impl_test.go +++ b/pkg/cmd/factory/factory_impl_test.go @@ -14,7 +14,6 @@ package factory import ( - "context" "testing" "github.com/golang/mock/gomock" @@ -33,8 +32,7 @@ func TestFactoryImplPdClient(t *testing.T) { t.Parallel() c := mock_factory.NewMockClientGetter(gomock.NewController(t)) f := factoryImpl{ClientGetter: c} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() cmdcontext.SetDefaultContext(ctx) var certAllowedCN []string diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index b5799afecb..0285e80a0c 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -232,7 +232,7 @@ func (o *Options) validate() error { if len(o.ServerPdAddr) == 0 { return cerror.ErrInvalidServerOption.GenWithStack("empty PD address") } - for _, ep := range strings.Split(o.ServerPdAddr, ",") { + for ep := range strings.SplitSeq(o.ServerPdAddr, ",") { // NOTICE: The configuration used here is the one that has been completed, // as it may be configured by the configuration file. if err := util.VerifyPdEndpoint(ep, o.ServerConfig.Security.IsTLSEnabled()); err != nil { diff --git a/pkg/cmd/util/helper.go b/pkg/cmd/util/helper.go index d0256d1b58..736a5d34dd 100644 --- a/pkg/cmd/util/helper.go +++ b/pkg/cmd/util/helper.go @@ -19,6 +19,7 @@ import ( "net/url" "os" "os/signal" + "slices" "strings" "syscall" @@ -117,7 +118,7 @@ func findProxyFields() []zap.Field { // StrictDecodeFile decodes the toml file strictly. If any item in confFile file is not mapped // into the Config struct, issue an error and stop the server from starting. -func StrictDecodeFile(path, component string, cfg interface{}, ignoreCheckItems ...string) error { +func StrictDecodeFile(path, component string, cfg any, ignoreCheckItems ...string) error { metaData, err := toml.DecodeFile(path, cfg) if err != nil { return errors.Trace(err) @@ -125,12 +126,7 @@ func StrictDecodeFile(path, component string, cfg interface{}, ignoreCheckItems // check if item is a ignoreCheckItem hasIgnoreItem := func(item []string) bool { - for _, ignoreCheckItem := range ignoreCheckItems { - if item[0] == ignoreCheckItem { - return true - } - } - return false + return slices.Contains(ignoreCheckItems, item[0]) } if undecoded := metaData.Undecoded(); len(undecoded) > 0 { @@ -179,7 +175,7 @@ func VerifyPdEndpoint(pdEndpoint string, useTLS bool) error { } // JSONPrint will output the data in JSON format. -func JSONPrint(cmd *cobra.Command, v interface{}) error { +func JSONPrint(cmd *cobra.Command, v any) error { data, err := json.MarshalIndent(v, "", " ") if err != nil { return err diff --git a/pkg/cmd/util/helper_test.go b/pkg/cmd/util/helper_test.go index b436a0551e..b245ee1467 100644 --- a/pkg/cmd/util/helper_test.go +++ b/pkg/cmd/util/helper_test.go @@ -45,7 +45,7 @@ func TestProxyFields(t *testing.T) { require.Nil(t, os.Unsetenv(env)) } - for i := 0; i < 3; i++ { + for i := range 3 { if (1< 0 { - addLen = q.chunkLength - c.r - if addLen > n { - addLen = n - } + addLen = min(q.chunkLength-c.r, n) copy(c.data[c.r:c.r+addLen], vals[cnt:cnt+addLen]) c.r += addLen q.size += addLen @@ -308,10 +299,7 @@ func (q *ChunkQueue[T]) PopMany(n int) ([]T, bool) { cnt := 0 for i := q.head; i < q.tail && cnt < n; i++ { c := q.chunks[i] - popLen := c.len() - if n-cnt < popLen { - popLen = n - cnt - } + popLen := min(n-cnt, c.len()) for j := 0; j < popLen; j++ { res[cnt+j] = c.data[c.l+j] c.data[c.l+j] = q.defaultValue diff --git a/pkg/container/queue/chunkqueue_test.go b/pkg/container/queue/chunkqueue_test.go index 7138d46ee8..e161763cbb 100644 --- a/pkg/container/queue/chunkqueue_test.go +++ b/pkg/container/queue/chunkqueue_test.go @@ -47,7 +47,7 @@ func TestChunkQueueCommon(t *testing.T) { // PushMany & PopMany elements := make([]int, 0, testCaseSize) require.True(t, q.Empty()) - for i := 0; i < testCaseSize; i++ { + for i := range testCaseSize { elements = append(elements, i) } q.PushMany(elements...) @@ -66,7 +66,7 @@ func TestChunkQueueCommon(t *testing.T) { q.PushMany(elements...) require.Equal(t, testCaseSize, q.Len()) require.False(t, q.Empty()) - for j := 0; j < testCaseSize; j++ { + for range testCaseSize { i := rand.Intn(testCaseSize) v := q.Peek(i) it := q.GetIterator(i) @@ -89,7 +89,7 @@ func TestChunkQueueCommon(t *testing.T) { require.True(t, ok) // Pop one by one - for i := 0; i < testCaseSize; i++ { + for i := range testCaseSize { h, ok := q.Head() require.Equal(t, i, h) require.True(t, ok) @@ -161,7 +161,7 @@ func doRandomTest[T comparable](t *testing.T, getVal func() T) { q := NewChunkQueue[T]() slice := make([]T, 0, 100) var val T - for i := 0; i < 100; i++ { + for i := range 100 { op := rand.Intn(4) if i == 99 { op = opPopAll @@ -174,7 +174,7 @@ func doRandomTest[T comparable](t *testing.T, getVal func() T) { case opPushMany: n := rand.Intn(1024) + 1 vals := make([]T, n) - for j := 0; j < n; j++ { + for range n { vals = append(vals, getVal()) } q.PushMany(vals...) @@ -201,14 +201,14 @@ func doRandomTest[T comparable](t *testing.T, getVal func() T) { popSlice := slice[0:n] slice = append(make([]T, 0, len(slice[n:])), slice[n:]...) - for i := 0; i < len(pops); i++ { + for i := range pops { require.Equal(t, popSlice[i], pops[i]) } } case opPopAll: pops := q.PopAll() require.Equal(t, len(pops), len(slice)) - for i := 0; i < len(pops); i++ { + for i := range pops { require.Equal(t, slice[i], pops[i]) } slice = slice[:0] @@ -231,7 +231,7 @@ func TestExpand(t *testing.T) { t.Parallel() q := NewChunkQueue[int]() - for i := 0; i < testCaseSize; i++ { + for range testCaseSize { q.Push(1) require.Equal(t, 1, q.Len()) freeSpace := q.Cap() - q.Len() @@ -248,7 +248,7 @@ func TestDequeueMany(t *testing.T) { q := NewChunkQueue[int]() x := testCaseSize - for v := 0; v < x; v++ { + for v := range x { q.Push(v) } f := 0 @@ -280,7 +280,7 @@ func TestRange(t *testing.T) { t.Parallel() q := NewChunkQueue[int]() - for i := 0; i < testCaseSize; i++ { + for i := range testCaseSize { q.Push(i) } @@ -329,7 +329,7 @@ func TestRangeAndPop(t *testing.T) { t.Parallel() q := NewChunkQueue[int]() - for i := 0; i < testCaseSize; i++ { + for i := range testCaseSize { q.Push(i) } @@ -393,7 +393,7 @@ func TestChunkQueuePushMany(t *testing.T) { func prepareSlice(n int) []int { data := make([]int, 0, n) - for i := 0; i < n; i++ { + for i := range n { data = append(data, i) } return data @@ -401,7 +401,7 @@ func prepareSlice(n int) []int { func prepareChunkQueue(n int) *ChunkQueue[int] { q := NewChunkQueue[int]() - for i := 0; i < n; i++ { + for i := range n { q.Push(i) } return q @@ -488,7 +488,7 @@ func BenchmarkPopMany(b *testing.B) { b.Run("PopMany-3rdPartyDeque", func(b *testing.B) { x := b.N q := deque.NewDeque() - for i := 0; i < x; i++ { + for i := range x { q.Enqueue(i) } ls := []int{x / 5, x / 5, x / 5, x / 5, x - x/5*4} @@ -542,7 +542,7 @@ func BenchmarkChunkQueueLoopPop(b *testing.B) { q.RangeAndPop(func(val int) bool { return val < 0 }) - for i := 0; i < x; i++ { + for range x { v, _ := q.Head() if v < 0 { break diff --git a/pkg/container/queue/iterator_test.go b/pkg/container/queue/iterator_test.go index 64e2ef6462..eef071ed53 100644 --- a/pkg/container/queue/iterator_test.go +++ b/pkg/container/queue/iterator_test.go @@ -28,7 +28,7 @@ const ( func TestChunkQueueIteratorPrevNext(t *testing.T) { t.Parallel() q := NewChunkQueue[int]() - for i := 0; i < iterTestSize; i++ { + for i := range iterTestSize { q.Push(i) } @@ -57,7 +57,7 @@ func BenchmarkIterate(b *testing.B) { b.Run("Iterate-ChunkQueue-by-iterator", func(b *testing.B) { q := NewChunkQueue[int]() n := b.N - for i := 0; i < n; i++ { + for i := range n { q.Push(i) } b.ResetTimer() @@ -75,7 +75,7 @@ func BenchmarkIterate(b *testing.B) { b.Run("Iterate-ChunkQueue-by-Peek", func(b *testing.B) { q := NewChunkQueue[int]() n := b.N - for i := 0; i < n; i++ { + for i := range n { q.Push(i) } b.ResetTimer() @@ -91,7 +91,7 @@ func BenchmarkIterate(b *testing.B) { b.Run("Iterate-ChunkQueue-by-Range", func(b *testing.B) { q := NewChunkQueue[int]() n := b.N - for i := 0; i < n; i++ { + for i := range n { q.Push(i) } b.ResetTimer() @@ -107,12 +107,12 @@ func BenchmarkIterate(b *testing.B) { b.Run("Iterate-Slice-byLoop", func(b *testing.B) { n := b.N q := make([]int, n) - for i := 0; i < n; i++ { + for i := range n { q[i] = i } b.ResetTimer() - for i := 0; i < len(q); i++ { + for i := range q { if q[i] != i { panic("error") } @@ -123,7 +123,7 @@ func BenchmarkIterate(b *testing.B) { q := deque.NewDeque() n := b.N - for i := 0; i < n; i++ { + for i := range n { q.Enqueue(i) } b.ResetTimer() @@ -140,12 +140,12 @@ func BenchmarkIterate(b *testing.B) { q := deque.NewDeque() n := b.N - for i := 0; i < n; i++ { + for i := range n { q.Enqueue(i) } b.ResetTimer() - for i := 0; i < n; i++ { + for i := range n { val := q.Peek(i) if val != i { panic("not equal") @@ -169,7 +169,7 @@ func TestChunkQueueGetIterator(t *testing.T) { require.False(t, oldIt.Valid(), oldIt.Prev()) require.True(t, q.Empty()) - for i := 0; i < iterTestSize; i++ { + for i := range iterTestSize { q.Push(i) } require.True(t, q.End().Index() < 0) @@ -179,7 +179,7 @@ func TestChunkQueueGetIterator(t *testing.T) { }) require.NotPanics(t, func() { - for i := 0; i < iterTestSize; i++ { + for i := range iterTestSize { it = q.GetIterator(i) require.Equal(t, i, it.Index(), it.Value(), q.Peek(i)) } diff --git a/pkg/container/sortmap/sort.go b/pkg/container/sortmap/sort.go index 1cb04e6db5..d577a3cf16 100644 --- a/pkg/container/sortmap/sort.go +++ b/pkg/container/sortmap/sort.go @@ -14,19 +14,18 @@ package sortmap import ( + "cmp" "sort" - - "golang.org/x/exp/constraints" ) // Pair represents the KV pairs in the input map of Sort. -type Pair[K constraints.Ordered, V any] struct { +type Pair[K cmp.Ordered, V any] struct { Key K Value V } // Sort converts an unordered golang map to a slice sorted by map key. -func Sort[K constraints.Ordered, V any](m map[K]V) []Pair[K, V] { +func Sort[K cmp.Ordered, V any](m map[K]V) []Pair[K, V] { s := make([]Pair[K, V], 0, len(m)) for k, v := range m { s = append(s, Pair[K, V]{k, v}) diff --git a/pkg/diff/checkpoint.go b/pkg/diff/checkpoint.go index c71d8574ae..7f21bd0ac7 100644 --- a/pkg/diff/checkpoint.go +++ b/pkg/diff/checkpoint.go @@ -126,7 +126,7 @@ func initChunks(ctx context.Context, db *sql.DB, instanceID, schema, table strin valuesPlaceholders := "(?, ?, ?, ?, ?, ?, ?, ?, ?)" valuesPlaceholdersArray := make([]string, 0, batch) - values := make([]interface{}, 0, 9*batch) + values := make([]any, 0, 9*batch) for i, chunk := range chunks { num++ @@ -303,7 +303,7 @@ func createCheckpointTable(ctx context.Context, db *sql.DB) error { // cleanCheckpoint deletes the table's checkpoint info in table `summary` and `chunk` func cleanCheckpoint(ctx context.Context, db *sql.DB, schema, table string) error { where := "`schema` = ? AND `table` = ?" - args := []interface{}{schema, table} + args := []any{schema, table} err := dbutil.DeleteRows(ctx, db, checkpointSchemaName, summaryTableName, where, args) if err != nil { diff --git a/pkg/diff/diff.go b/pkg/diff/diff.go index 6d6ebdc0cb..1f088dc340 100644 --- a/pkg/diff/diff.go +++ b/pkg/diff/diff.go @@ -498,7 +498,7 @@ func (t *TableDiff) compareChecksum(ctx context.Context, chunk *ChunkRange) (boo ) defer close(checksumInfoCh) - getChecksum := func(db *sql.DB, schema, table, limitRange string, tbInfo *model.TableInfo, args []interface{}, tp string) { + getChecksum := func(db *sql.DB, schema, table, limitRange string, tbInfo *model.TableInfo, args []any, tp string) { beginTime := time.Now() checksum, err := dbutil.GetCRC32Checksum(ctx1, db, schema, table, tbInfo, limitRange, args) cost := time.Since(beginTime) @@ -1017,7 +1017,7 @@ func compareData(map1, map2 map[string]*dbutil.ColumnData, orderKeyCols []*model } func getChunkRows(ctx context.Context, db *sql.DB, schema, table string, tableInfo *model.TableInfo, where string, - args []interface{}, collation string, + args []any, collation string, ) (*sql.Rows, []*model.ColumnInfo, error) { _, orderKeyCols := dbutil.SelectUniqueOrderKey(tableInfo) diff --git a/pkg/diff/merge.go b/pkg/diff/merge.go index a36f176e93..d9da7d652a 100644 --- a/pkg/diff/merge.go +++ b/pkg/diff/merge.go @@ -94,12 +94,12 @@ func (r RowDatas) Less(i, j int) bool { func (r RowDatas) Swap(i, j int) { r.Rows[i], r.Rows[j] = r.Rows[j], r.Rows[i] } // Push implements heap.Interface's Push function -func (r *RowDatas) Push(x interface{}) { +func (r *RowDatas) Push(x any) { r.Rows = append(r.Rows, x.(RowData)) } // Pop implements heap.Interface's Pop function -func (r *RowDatas) Pop() interface{} { +func (r *RowDatas) Pop() any { if len(r.Rows) == 0 { return nil } diff --git a/pkg/diff/merge_test.go b/pkg/diff/merge_test.go index ca08055c53..fe7d180430 100644 --- a/pkg/diff/merge_test.go +++ b/pkg/diff/merge_test.go @@ -56,7 +56,7 @@ func (s *testMergerSuite) TestMerge(c *check.C) { }) } - for i := 0; i < len(ids); i++ { + for i := range ids { rowData := heap.Pop(rowDatas).(RowData) id := string(rowData.Data["id"].Data) name := string(rowData.Data["name"].Data) diff --git a/pkg/diff/spliter_test.go b/pkg/diff/spliter_test.go index 77026ace56..40a526c583 100644 --- a/pkg/diff/spliter_test.go +++ b/pkg/diff/spliter_test.go @@ -42,14 +42,14 @@ func (s *testSpliterSuite) TestSplitRangeByRandom(c *check.C) { createTableSQL string splitCount int originChunk *ChunkRange - randomValues [][]interface{} + randomValues [][]any expectResult []chunkResult }{ { "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`a`, `b`))", 3, NewChunkRange().copyAndUpdate("a", "0", "10").copyAndUpdate("b", "a", "z"), - [][]interface{}{ + [][]any{ {5, 7}, {"g", "n"}, }, @@ -69,7 +69,7 @@ func (s *testSpliterSuite) TestSplitRangeByRandom(c *check.C) { "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`b`))", 3, NewChunkRange().copyAndUpdate("b", "a", "z"), - [][]interface{}{ + [][]any{ {"g", "n"}, }, []chunkResult{ @@ -88,7 +88,7 @@ func (s *testSpliterSuite) TestSplitRangeByRandom(c *check.C) { "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`b`))", 2, NewChunkRange().copyAndUpdate("b", "a", "z"), - [][]interface{}{ + [][]any{ {"g"}, }, []chunkResult{ @@ -104,7 +104,7 @@ func (s *testSpliterSuite) TestSplitRangeByRandom(c *check.C) { "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`b`))", 3, NewChunkRange().copyAndUpdate("b", "a", "z"), - [][]interface{}{ + [][]any{ {}, }, []chunkResult{ @@ -142,13 +142,13 @@ func (s *testSpliterSuite) TestRandomSpliter(c *check.C) { testCases := []struct { createTableSQL string count int - randomValues [][]interface{} + randomValues [][]any expectResult []chunkResult }{ { "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`a`, `b`))", 10, - [][]interface{}{ + [][]any{ {1, 2, 3, 4, 5}, {"a", "b", "c", "d", "e"}, }, @@ -176,7 +176,7 @@ func (s *testSpliterSuite) TestRandomSpliter(c *check.C) { }, { "create table `test`.`test`(`a` int, `b` varchar(10), `c` float, `d` datetime, primary key(`b`))", 10, - [][]interface{}{ + [][]any{ {"a", "b", "c", "d", "e"}, }, []chunkResult{ @@ -232,7 +232,7 @@ func (s *testSpliterSuite) TestRandomSpliter(c *check.C) { } } -func createFakeResultForRandomSplit(mock sqlmock.Sqlmock, count int, randomValues [][]interface{}) { +func createFakeResultForRandomSplit(mock sqlmock.Sqlmock, count int, randomValues [][]any) { if count > 0 { // generate fake result for get the row count of this table countRows := sqlmock.NewRows([]string{"cnt"}).AddRow(count) @@ -259,15 +259,15 @@ func (s *testSpliterSuite) TestBucketSpliter(c *check.C) { testCases := []struct { chunkSize int - aRandomValues []interface{} - bRandomValues []interface{} + aRandomValues []any + bRandomValues []any expectResult []chunkResult }{ { // chunk size less than the count of bucket 64, and the bucket's count 64 >= 32, so will split by random in every bucket 32, - []interface{}{32, 32 * 3, 32 * 5, 32 * 7, 32 * 9}, - []interface{}{6, 6 * 3, 6 * 5, 6 * 7, 6 * 9}, + []any{32, 32 * 3, 32 * 5, 32 * 7, 32 * 9}, + []any{6, 6 * 3, 6 * 5, 6 * 7, 6 * 9}, []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", @@ -439,7 +439,7 @@ func (s *testSpliterSuite) TestBucketSpliter(c *check.C) { } } -func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandomValues []interface{}) { +func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandomValues []any) { /* +---------+------------+-------------+----------+-----------+-------+---------+-------------+-------------+ | Db_name | Table_name | Column_name | Is_index | Bucket_id | Count | Repeats | Lower_Bound | Upper_Bound | @@ -454,7 +454,7 @@ func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandom // Mock query with subquery to get all table_ids (main table + partitions) at once statsRows := sqlmock.NewRows([]string{"is_index", "hist_id", "bucket_id", "count", "lower_bound", "upper_bound"}) - for i := 0; i < 5; i++ { + for i := range 5 { // Encode index bounds as real encoded keys: PRIMARY(a, b) where both a and b are integers. lowerA, lowerB := i*64, i*12 upperA, upperB := (i+1)*64-1, (i+1)*12-1 @@ -471,7 +471,7 @@ func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandom WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg()). WillReturnRows(statsRows) - for i := 0; i < len(aRandomValues); i++ { + for i := range aRandomValues { aRandomRows := sqlmock.NewRows([]string{"a"}) aRandomRows.AddRow(aRandomValues[i]) mock.ExpectQuery("ORDER BY rand_value").WillReturnRows(aRandomRows) diff --git a/pkg/diff/util.go b/pkg/diff/util.go index 3d8355eb54..6c8bb40afc 100644 --- a/pkg/diff/util.go +++ b/pkg/diff/util.go @@ -24,8 +24,8 @@ import ( "go.uber.org/zap" ) -func sliceToMap(slice []string) map[string]interface{} { - sMap := make(map[string]interface{}) +func sliceToMap(slice []string) map[string]any { + sMap := make(map[string]any) for _, str := range slice { sMap[str] = struct{}{} } @@ -121,8 +121,8 @@ func rowToString(row map[string]*dbutil.ColumnData) string { return s.String() } -func stringsToInterfaces(strs []string) []interface{} { - is := make([]interface{}, 0, len(strs)) +func stringsToInterfaces(strs []string) []any { + is := make([]any, 0, len(strs)) for _, str := range strs { is = append(is, str) } diff --git a/pkg/election/elector_test.go b/pkg/election/elector_test.go index ddca2a0556..b97d2286e7 100644 --- a/pkg/election/elector_test.go +++ b/pkg/election/elector_test.go @@ -68,7 +68,7 @@ func TestElectorBasic(t *testing.T) { ) firstLeaderID := make(chan string, 1) const electorCount = 5 - for i := 0; i < electorCount; i++ { + for i := range electorCount { id := fmt.Sprintf("elector-%d", i) config := election.Config{ ID: id, @@ -91,13 +91,11 @@ func TestElectorBasic(t *testing.T) { require.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := elector.RunElection(ctx) require.Error(t, err) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) electors = append(electors, elector) configs = append(configs, config) @@ -247,14 +245,12 @@ func TestElectorRenewFailure(t *testing.T) { require.NoError(t, err) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := e1.RunElection(ctx) require.Error(t, err) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) // Wait for leader to be elected. require.Eventually(t, func() bool { @@ -277,13 +273,11 @@ func TestElectorRenewFailure(t *testing.T) { }) require.NoError(t, err) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := e2.RunElection(ctx) require.Error(t, err) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) // Make s1 fail and wait for s2 to be elected. s1Err.Store(errors.New("connection error")) @@ -369,13 +363,11 @@ func TestLeaderCallbackUnexpectedExit(t *testing.T) { require.NoError(t, err) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := e1.RunElection(ctx) require.Error(t, err) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) // Wait for leader to be elected. require.Eventually(t, func() bool { @@ -397,13 +389,11 @@ func TestLeaderCallbackUnexpectedExit(t *testing.T) { RenewDeadline: renewDeadline, }) require.NoError(t, err) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := e2.RunElection(ctx) require.Error(t, err) require.Equal(t, context.Canceled, errors.Cause(err)) - }() + }) // Make elector 1 leader callback return error. e1CallbackErr.Store(errors.New("callback error")) diff --git a/pkg/election/storage_orm.go b/pkg/election/storage_orm.go index 52533ccf1d..81ca9a0963 100644 --- a/pkg/election/storage_orm.go +++ b/pkg/election/storage_orm.go @@ -38,7 +38,7 @@ func (r Record) Value() (driver.Value, error) { } // Scan implements the sql.Scanner interface -func (r *Record) Scan(value interface{}) error { +func (r *Record) Scan(value any) error { b, ok := value.([]byte) if !ok { return errors.New("type assertion to []byte failed") diff --git a/pkg/election/storage_sql_test.go b/pkg/election/storage_sql_test.go index 6b4ee9d8cd..8ae061979b 100644 --- a/pkg/election/storage_sql_test.go +++ b/pkg/election/storage_sql_test.go @@ -140,8 +140,7 @@ func TestInMemorySQLStorage(t *testing.T) { s, err := NewInMemorySQLStorage(dbName, "leader_election") require.NoError(t, err) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() record := &Record{ LeaderID: "id1", diff --git a/pkg/errors/helper.go b/pkg/errors/helper.go index 0bbd574fa5..ee184b4c84 100644 --- a/pkg/errors/helper.go +++ b/pkg/errors/helper.go @@ -27,7 +27,7 @@ import ( // as cause error. // If given `err` is nil, returns a nil error, which a the different behavior // against `Wrap` function in pingcap/errors. -func WrapError(rfcError *errors.Error, err error, args ...interface{}) error { +func WrapError(rfcError *errors.Error, err error, args ...any) error { if err == nil { return nil } @@ -170,7 +170,7 @@ func IsCliUnprintableError(err error) bool { } // WrapChangefeedUnretryableErr wraps an error into ErrChangefeedUnRetryable. -func WrapChangefeedUnretryableErr(err error, args ...interface{}) error { +func WrapChangefeedUnretryableErr(err error, args ...any) error { return WrapError(ErrChangefeedUnretryable, err, args...) } diff --git a/pkg/errors/helper_test.go b/pkg/errors/helper_test.go index 6c705f8325..8fc417eee4 100644 --- a/pkg/errors/helper_test.go +++ b/pkg/errors/helper_test.go @@ -33,13 +33,13 @@ func TestWrapError(t *testing.T) { err error isNil bool expected string - args []interface{} + args []any }{ {ErrDecodeFailed, nil, true, "", nil}, { ErrDecodeFailed, err, false, "[CDC:ErrDecodeFailed]decode failed: args data: cause error", - []interface{}{"args data"}, + []any{"args data"}, }, } ) diff --git a/pkg/etcd/client.go b/pkg/etcd/client.go index 77e5beafb4..01b3c22d5d 100644 --- a/pkg/etcd/client.go +++ b/pkg/etcd/client.go @@ -418,7 +418,7 @@ func CreateRawEtcdClient(securityConf *security.Credential, grpcDialOption grpc. select { case <-client.Ctx().Done(): log.Info("etcd client is closed, exit health check goroutine") - checker.Range(func(key, value interface{}) bool { + checker.Range(func(key, value any) bool { client := value.(*healthyClient) client.Close() return true @@ -486,15 +486,15 @@ func (checker *healthyChecker) patrol(ctx context.Context) []string { // See https://github.com/etcd-io/etcd/blob/85b640cee793e25f3837c47200089d14a8392dc7/etcdctl/ctlv3/command/ep_command.go#L105-L145 var wg sync.WaitGroup count := 0 - checker.Range(func(key, value interface{}) bool { + checker.Range(func(key, value any) bool { count++ return true }) hch := make(chan string, count) healthyList := make([]string, 0, count) - checker.Range(func(key, value interface{}) bool { + checker.Range(func(key, value any) bool { wg.Add(1) - go func(key, value interface{}) { + go func(key, value any) { defer wg.Done() ep := key.(string) client := value.(*healthyClient) @@ -539,7 +539,7 @@ func (checker *healthyChecker) update(eps []string) { } checker.addClient(ep, time.Now()) } - checker.Range(func(key, value interface{}) bool { + checker.Range(func(key, value any) bool { ep := key.(string) if _, exist := updateEps[ep]; !exist { if client, ok := value.(*healthyClient); ok { diff --git a/pkg/etcd/client_test.go b/pkg/etcd/client_test.go index 199897c559..6226739707 100644 --- a/pkg/etcd/client_test.go +++ b/pkg/etcd/client_test.go @@ -90,8 +90,7 @@ func TestRetry(t *testing.T) { require.NotNil(t, err) require.Containsf(t, errors.Cause(err).Error(), "mock error", "err:%v", err.Error()) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Test Txn case // case 0: normal diff --git a/pkg/etcd/etcd.go b/pkg/etcd/etcd.go index c88053ff19..64ecce9314 100644 --- a/pkg/etcd/etcd.go +++ b/pkg/etcd/etcd.go @@ -653,7 +653,7 @@ func GcServiceIDForTest() string { // getFreeListenURLs get free ports and localhost as url. func getFreeListenURLs(n int) (urls []*url.URL, retErr error) { - for i := 0; i < n; i++ { + for range n { u, err := url.Parse(tempurl.Alloc()) if err != nil { retErr = errors.Trace(err) diff --git a/pkg/etcd/etcd_test.go b/pkg/etcd/etcd_test.go index daa83ecd0e..c425ee943c 100644 --- a/pkg/etcd/etcd_test.go +++ b/pkg/etcd/etcd_test.go @@ -283,8 +283,7 @@ func TestGetAllCaptureLeases(t *testing.T) { s.SetUpTest(t) defer s.TearDownTest(t) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() testCases := []*model.CaptureInfo{ { ID: "a3f41a6a-3c31-44f4-aa27-344c1b8cd658", @@ -359,7 +358,7 @@ func TestGetOwnerRevision(t *testing.T) { // checks that the global monotonicity is guaranteed. wg.Add(3) - for i := 0; i < 3; i++ { + for i := range 3 { i := i go func() { defer wg.Done() diff --git a/pkg/etcd/util_test.go b/pkg/etcd/util_test.go index 248078ec19..6ddadf6d05 100644 --- a/pkg/etcd/util_test.go +++ b/pkg/etcd/util_test.go @@ -24,7 +24,7 @@ import ( func TestGetRevisionFromWatchOpts(t *testing.T) { t.Parallel() - for i := 0; i < 100; i++ { + for range 100 { rev := rand.Int63n(math.MaxInt64) opt := clientv3.WithRev(rev) require.Equal(t, getRevisionFromWatchOpts(opt), rev) diff --git a/pkg/filter/expr_filter_bench_test.go b/pkg/filter/expr_filter_bench_test.go index 8048be6e59..a2c1415b13 100644 --- a/pkg/filter/expr_filter_bench_test.go +++ b/pkg/filter/expr_filter_bench_test.go @@ -70,8 +70,8 @@ func BenchmarkSkipDML(b *testing.B) { // set columns to non nil to indicate this case is for insert // set columns to nil to indicate this case is for delete columns []*model.Column - preRow []interface{} - row []interface{} + preRow []any + row []any ignore bool } @@ -83,7 +83,7 @@ func BenchmarkSkipDML(b *testing.B) { columns: []*model.Column{ {Name: "none"}, }, - row: []interface{}{999, "Will", 39, "male"}, + row: []any{999, "Will", 39, "male"}, ignore: true, }, { // insert @@ -95,7 +95,7 @@ func BenchmarkSkipDML(b *testing.B) { columns: []*model.Column{ {Name: "none"}, }, - row: []interface{}{999, "Will", 39, "male"}, + row: []any{999, "Will", 39, "male"}, ignore: true, }, { // update @@ -105,11 +105,11 @@ func BenchmarkSkipDML(b *testing.B) { preColumns: []*model.Column{ {Name: "none"}, }, - preRow: []interface{}{876, "Li", 45, "female"}, + preRow: []any{876, "Li", 45, "female"}, columns: []*model.Column{ {Name: "none"}, }, - row: []interface{}{1, "Dongmen", 20, "male"}, + row: []any{1, "Dongmen", 20, "male"}, ignore: true, }, { // delete @@ -119,7 +119,7 @@ func BenchmarkSkipDML(b *testing.B) { preColumns: []*model.Column{ {Name: "none"}, }, - preRow: []interface{}{876, "Li", 45, "female"}, + preRow: []any{876, "Li", 45, "female"}, ignore: true, }, } diff --git a/pkg/filter/expr_filter_test.go b/pkg/filter/expr_filter_test.go index 843a1f9287..0eb5e1a752 100644 --- a/pkg/filter/expr_filter_test.go +++ b/pkg/filter/expr_filter_test.go @@ -31,7 +31,7 @@ import ( ) // adjustBinaryProtocolForDatumWithoutVirtualCol converts the data in binlog to TiDB datum. -func adjustBinaryProtocolForDatumWithoutVirtualCol(ctx sessionctx.Context, data []interface{}, cols []*timodel.ColumnInfo) ([]types.Datum, error) { +func adjustBinaryProtocolForDatumWithoutVirtualCol(ctx sessionctx.Context, data []any, cols []*timodel.ColumnInfo) ([]types.Datum, error) { ret := make([]types.Datum, 0, len(data)) colIndex := 0 for _, d := range data { @@ -66,8 +66,8 @@ func TestShouldSkipDMLBasic(t *testing.T) { // set columns to non nil to indicate this case is for insert // set columns to nil to indicate this case is for delete columns []*model.ColumnData - preRow []interface{} - row []interface{} + preRow []any + row []any ignore bool } @@ -98,7 +98,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{999, "Will", 39, "male"}, + row: []any{999, "Will", 39, "male"}, ignore: false, }, { // schema name does not configure in matcher, no rule to filter it @@ -107,7 +107,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{888, "Li", 45, "male"}, + row: []any{888, "Li", 45, "male"}, ignore: false, }, { // insert @@ -116,7 +116,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "Dongmen", 20, "male"}, + row: []any{1, "Dongmen", 20, "male"}, ignore: true, }, { // insert @@ -125,7 +125,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{2, "Rustin", 18, "male"}, + row: []any{2, "Rustin", 18, "male"}, ignore: false, }, { // insert @@ -134,7 +134,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{3, "Susan", 3, "female"}, + row: []any{3, "Susan", 3, "female"}, ignore: true, }, { // delete @@ -143,7 +143,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{4, "Helen", 18, "female"}, + preRow: []any{4, "Helen", 18, "female"}, ignore: false, }, { // delete @@ -152,7 +152,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{5, "Madonna", 32, "female"}, + preRow: []any{5, "Madonna", 32, "female"}, ignore: true, }, { // delete @@ -161,7 +161,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{6, "Madison", 48, "male"}, + preRow: []any{6, "Madison", 48, "male"}, ignore: false, }, { // update, filler by new value @@ -170,11 +170,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{7, "Marry", 28, "female"}, + preRow: []any{7, "Marry", 28, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{7, "Marry", 32, "female"}, + row: []any{7, "Marry", 32, "female"}, ignore: true, }, { // update @@ -183,11 +183,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{8, "Marilyn", 18, "female"}, + preRow: []any{8, "Marilyn", 18, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{8, "Monroe", 22, "female"}, + row: []any{8, "Monroe", 22, "female"}, ignore: false, }, { // update, filter by old value @@ -196,11 +196,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{9, "Andreja", 25, "male"}, + preRow: []any{9, "Andreja", 25, "male"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{9, "Andreja", 25, "female"}, + row: []any{9, "Andreja", 25, "female"}, ignore: true, }, }, @@ -226,7 +226,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "Dongmen", 20, "male"}, + row: []any{1, "Dongmen", 20, "male"}, ignore: true, }, { // insert @@ -235,7 +235,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{2, "Rustin", 18, "male"}, + row: []any{2, "Rustin", 18, "male"}, ignore: false, }, { // insert @@ -244,7 +244,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{3, "Susan", 3, "female"}, + row: []any{3, "Susan", 3, "female"}, ignore: true, }, { // delete @@ -253,7 +253,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{4, "Helen", 18, "female"}, + preRow: []any{4, "Helen", 18, "female"}, ignore: false, }, { // delete @@ -262,7 +262,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{5, "Madonna", 32, "female"}, + preRow: []any{5, "Madonna", 32, "female"}, ignore: true, }, { // delete @@ -271,7 +271,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{6, "Madison", 48, "male"}, + preRow: []any{6, "Madison", 48, "male"}, ignore: false, }, { // update, filler by new value @@ -280,11 +280,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{7, "Marry", 28, "female"}, + preRow: []any{7, "Marry", 28, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{7, "Marry", 32, "female"}, + row: []any{7, "Marry", 32, "female"}, ignore: true, }, { // update @@ -293,11 +293,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{8, "Marilyn", 18, "female"}, + preRow: []any{8, "Marilyn", 18, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{8, "Monroe", 22, "female"}, + row: []any{8, "Monroe", 22, "female"}, ignore: false, }, { // update, filter by old value @@ -306,11 +306,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{9, "Andreja", 25, "male"}, + preRow: []any{9, "Andreja", 25, "male"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{9, "Andreja", 25, "female"}, + row: []any{9, "Andreja", 25, "female"}, ignore: true, }, }, @@ -332,7 +332,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "apple", 12888}, + row: []any{1, "apple", 12888}, ignore: true, }, { // insert @@ -341,7 +341,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{2, "microsoft", 5888}, + row: []any{2, "microsoft", 5888}, ignore: false, }, }, @@ -363,7 +363,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "ζŽη™½", "ι™ε€œζ€"}, + row: []any{1, "ζŽη™½", "ι™ε€œζ€"}, ignore: true, }, { // insert @@ -372,7 +372,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{2, "ζœη”«", "ηŸ³ε£•ε"}, + row: []any{2, "ζœη”«", "ηŸ³ε£•ε"}, ignore: false, }, { // insert @@ -381,7 +381,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{4, "屈原", "离ιͺš"}, + row: []any{4, "屈原", "离ιͺš"}, ignore: true, }, { // insert @@ -390,7 +390,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{3, "θΎ›εΌƒη–Ύ", "δΌ—ι‡Œε―»δ»–εƒη™ΎεΊ¦"}, + row: []any{3, "θΎ›εΌƒη–Ύ", "δΌ—ι‡Œε―»δ»–εƒη™ΎεΊ¦"}, ignore: true, }, }, @@ -414,7 +414,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "Spring", "January", "March"}, + row: []any{1, "Spring", "January", "March"}, ignore: false, }, { // do not ignore any event of test.season table @@ -423,11 +423,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{2, "Summer", "April", "June"}, + preRow: []any{2, "Summer", "April", "June"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{2, "Summer", "April", "July"}, + row: []any{2, "Summer", "April", "July"}, ignore: false, }, { // ignore insert event of test.autumn table @@ -436,7 +436,7 @@ func TestShouldSkipDMLBasic(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{3, "Autumn", "July", "September"}, + row: []any{3, "Autumn", "July", "September"}, ignore: true, }, { // ignore update event of test.winter table @@ -445,11 +445,11 @@ func TestShouldSkipDMLBasic(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{4, "Winter", "October", "January"}, + preRow: []any{4, "Winter", "October", "January"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{4, "Winter", "October", "December"}, + row: []any{4, "Winter", "October", "December"}, ignore: true, }, }, @@ -504,8 +504,8 @@ func TestShouldSkipDMLError(t *testing.T) { // set columns to non nil to indicate this case is for insert // set columns to nil to indicate this case is for delete columns []*model.ColumnData - preRow []interface{} - row []interface{} + preRow []any + row []any ignore bool err error errMsg string @@ -538,7 +538,7 @@ func TestShouldSkipDMLError(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{999, "Will", 39, "male"}, + row: []any{999, "Will", 39, "male"}, ignore: false, err: cerror.ErrExpressionColumnNotFound, errMsg: "Cannot find column 'mather' from table 'test.student' in", @@ -549,11 +549,11 @@ func TestShouldSkipDMLError(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{876, "Li", 45, "female"}, + preRow: []any{876, "Li", 45, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "Dongmen", 20, "male"}, + row: []any{1, "Dongmen", 20, "male"}, ignore: false, err: cerror.ErrExpressionParseFailed, errMsg: "There is a syntax error in", @@ -564,7 +564,7 @@ func TestShouldSkipDMLError(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{876, "Li", 45, "female"}, + preRow: []any{876, "Li", 45, "female"}, ignore: false, err: cerror.ErrExpressionParseFailed, errMsg: "There is a syntax error in", @@ -624,8 +624,8 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { // set columns to non nil to indicate this case is for insert // set columns to nil to indicate this case is for delete columns []*model.ColumnData - preRow []interface{} - row []interface{} + preRow []any + row []any ignore bool err error errMsg string @@ -658,7 +658,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{999, "Will", 39, "male"}, + row: []any{999, "Will", 39, "male"}, ignore: false, err: cerror.ErrExpressionColumnNotFound, errMsg: "Cannot find column 'mather' from table 'test.student' in", @@ -671,7 +671,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{999, "Will", 39, "male", "Marry"}, + row: []any{999, "Will", 39, "male", "Marry"}, ignore: false, }, { // update @@ -680,11 +680,11 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{876, "Li", 45, "female"}, + preRow: []any{876, "Li", 45, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "Dongmen", 20, "male"}, + row: []any{1, "Dongmen", 20, "male"}, ignore: true, }, { // delete @@ -693,7 +693,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{876, "Li", 45, "female", "Maria"}, + preRow: []any{876, "Li", 45, "female", "Maria"}, ignore: true, }, }, @@ -718,7 +718,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{999, "Will", 39, "male", "Apple"}, + row: []any{999, "Will", 39, "male", "Apple"}, ignore: true, }, { // insert @@ -727,7 +727,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{11, "Tom", 21, "male", "FaceBook"}, + row: []any{11, "Tom", 21, "male", "FaceBook"}, ignore: false, }, { // update @@ -736,11 +736,11 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{876, "Li", 45, "female"}, + preRow: []any{876, "Li", 45, "female"}, columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{1, "Dongmen", 20, "male"}, + row: []any{1, "Dongmen", 20, "male"}, ignore: true, }, { // delete @@ -749,7 +749,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { preColumns: []*model.ColumnData{ {ColumnID: 0}, }, - preRow: []interface{}{876, "Li", 45, "female", "Google"}, + preRow: []any{876, "Li", 45, "female", "Google"}, ignore: true, }, { // insert @@ -759,7 +759,7 @@ func TestShouldSkipDMLTableUpdated(t *testing.T) { columns: []*model.ColumnData{ {ColumnID: 0}, }, - row: []interface{}{999, "Will", 39, "male"}, + row: []any{999, "Will", 39, "male"}, ignore: false, err: cerror.ErrExpressionColumnNotFound, errMsg: "Cannot find column 'company' from table 'test.worker' in", diff --git a/pkg/filter/filter.go b/pkg/filter/filter.go index 6b343daf23..912558bbfa 100644 --- a/pkg/filter/filter.go +++ b/pkg/filter/filter.go @@ -14,6 +14,8 @@ package filter import ( + "slices" + timodel "github.com/pingcap/tidb/pkg/meta/model" tfilter "github.com/pingcap/tidb/pkg/util/table-filter" "github.com/pingcap/tiflow/cdc/model" @@ -244,12 +246,7 @@ func (f *filter) Verify(tableInfos []*model.TableInfo) error { } func (f *filter) shouldIgnoreStartTs(ts uint64) bool { - for _, ignoreTs := range f.ignoreTxnStartTs { - if ignoreTs == ts { - return true - } - } - return false + return slices.Contains(f.ignoreTxnStartTs, ts) } func isAllowedDDL(actionType timodel.ActionType) bool { diff --git a/pkg/filter/sql_event_filter_test.go b/pkg/filter/sql_event_filter_test.go index d7b17ce882..7aef3a36a2 100644 --- a/pkg/filter/sql_event_filter_test.go +++ b/pkg/filter/sql_event_filter_test.go @@ -465,7 +465,6 @@ func TestShouldSkipDML(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() f, err := newSQLEventFilter(tc.cfg) diff --git a/pkg/filter/utils.go b/pkg/filter/utils.go index aa7fb4b1fa..96b501e9fc 100644 --- a/pkg/filter/utils.go +++ b/pkg/filter/utils.go @@ -15,6 +15,7 @@ package filter import ( "fmt" + "slices" "strings" timodel "github.com/pingcap/tidb/pkg/meta/model" @@ -119,12 +120,7 @@ var alterTableSubType = []timodel.ActionType{ // isAlterTable returns true if the given job type is alter table's subtype. func isAlterTable(jobType timodel.ActionType) bool { - for _, t := range alterTableSubType { - if t == jobType { - return true - } - } - return false + return slices.Contains(alterTableSubType, jobType) } // SupportedEventTypes returns the supported event types. diff --git a/pkg/fsutil/file_allocator.go b/pkg/fsutil/file_allocator.go index acf4f203d9..c25a47afc5 100644 --- a/pkg/fsutil/file_allocator.go +++ b/pkg/fsutil/file_allocator.go @@ -52,11 +52,9 @@ func NewFileAllocator(dir string, prefix string, size int64) *FileAllocator { doneCh: make(chan struct{}), } - allocator.wg.Add(1) - go func() { - defer allocator.wg.Done() + allocator.wg.Go(func() { allocator.run() - }() + }) return allocator } diff --git a/pkg/fsutil/file_allocator_test.go b/pkg/fsutil/file_allocator_test.go index 44c6bb91f5..5137ac3623 100644 --- a/pkg/fsutil/file_allocator_test.go +++ b/pkg/fsutil/file_allocator_test.go @@ -66,7 +66,7 @@ func benchmarkWriteData(b *testing.B, size int, useFileAlloctor bool) { } data := make([]byte, size) - for i := 0; i < size; i++ { + for i := range size { data[i] = byte(i) } diff --git a/pkg/importer/db.go b/pkg/importer/db.go index 3242cd0539..8f6037a3f0 100644 --- a/pkg/importer/db.go +++ b/pkg/importer/db.go @@ -65,7 +65,7 @@ func uniqInt64Value(column *column, max int64) int64 { func genRowDatas(table *table, count int) ([]string, error) { datas := make([]string, 0, count) - for i := 0; i < count; i++ { + for range count { data, err := genRowData(table) if err != nil { return nil, errors.Trace(err) @@ -242,7 +242,7 @@ func closeDB(db *sql.DB) error { func createDBs(cfg dbutil.DBConfig, count int) ([]*sql.DB, error) { dbs := make([]*sql.DB, 0, count) - for i := 0; i < count; i++ { + for range count { db, err := createDB(cfg) if err != nil { return nil, errors.Trace(err) diff --git a/pkg/importer/job.go b/pkg/importer/job.go index 9ed994618b..6af8035190 100644 --- a/pkg/importer/job.go +++ b/pkg/importer/job.go @@ -23,7 +23,7 @@ import ( ) func addJobs(jobCount int, jobChan chan struct{}) { - for i := 0; i < jobCount; i++ { + for range jobCount { jobChan <- struct{}{} } @@ -72,7 +72,7 @@ func doJob(table *table, db *sql.DB, batch int, jobChan chan struct{}, doneChan } func doWait(doneChan chan struct{}, start time.Time, jobCount int, workerCount int) { - for i := 0; i < workerCount; i++ { + for range workerCount { <-doneChan } @@ -96,7 +96,7 @@ func doProcess(table *table, dbs []*sql.DB, jobCount int, workerCount int, batch start := time.Now() go addJobs(jobCount, jobChan) - for i := 0; i < workerCount; i++ { + for i := range workerCount { go doJob(table, dbs[i], batch, jobChan, doneChan) } diff --git a/pkg/importer/parser.go b/pkg/importer/parser.go index b13d3fb92b..9a702c2653 100644 --- a/pkg/importer/parser.go +++ b/pkg/importer/parser.go @@ -73,8 +73,8 @@ func (col *column) parseRule(kvs []string) { log.Fatal("parseRule", zap.Error(err)) } } else if key == "set" { - fields := strings.Split(value, ",") - for _, field := range fields { + fields := strings.SplitSeq(value, ",") + for field := range fields { col.set = append(col.set, strings.TrimSpace(field)) } } @@ -92,8 +92,8 @@ func (col *column) parseColumnComment() { content = comment[start+2 : end] } - fields := strings.Split(content, ";") - for _, field := range fields { + fields := strings.SplitSeq(content, ";") + for field := range fields { field = strings.TrimSpace(field) kvs := strings.Split(field, "=") col.parseRule(kvs) @@ -129,12 +129,12 @@ type table struct { } func (t *table) printColumns() string { - ret := "" + var ret strings.Builder for _, col := range t.columns { - ret += fmt.Sprintf("%v", col) + ret.WriteString(fmt.Sprintf("%v", col)) } - return ret + return ret.String() } func (t *table) String() string { @@ -142,23 +142,24 @@ func (t *table) String() string { return "" } - ret := fmt.Sprintf("[table]name: %s\n", t.name) - ret += "[table]columns:\n" - ret += t.printColumns() + var ret strings.Builder + ret.WriteString(fmt.Sprintf("[table]name: %s\n", t.name)) + ret.WriteString("[table]columns:\n") + ret.WriteString(t.printColumns()) - ret += fmt.Sprintf("[table]column list: %s\n", t.columnList) + ret.WriteString(fmt.Sprintf("[table]column list: %s\n", t.columnList)) - ret += "[table]indices:\n" + ret.WriteString("[table]indices:\n") for k, v := range t.indices { - ret += fmt.Sprintf("key->%s, value->%v", k, v) + ret.WriteString(fmt.Sprintf("key->%s, value->%v", k, v)) } - ret += "[table]unique indices:\n" + ret.WriteString("[table]unique indices:\n") for k, v := range t.uniqIndices { - ret += fmt.Sprintf("key->%s, value->%v", k, v) + ret.WriteString(fmt.Sprintf("key->%s, value->%v", k, v)) } - return ret + return ret.String() } func newTable() *table { diff --git a/pkg/label/label_test.go b/pkg/label/label_test.go index fb6799cd6a..55b1c23201 100644 --- a/pkg/label/label_test.go +++ b/pkg/label/label_test.go @@ -51,7 +51,6 @@ func TestNewKey(t *testing.T) { t.Parallel() for _, tc := range cases { - tc := tc t.Run(tc.str, func(t *testing.T) { t.Parallel() res, err := NewKey(tc.str) @@ -69,7 +68,6 @@ func TestNewValue(t *testing.T) { t.Parallel() for _, tc := range cases { - tc := tc t.Run(tc.str, func(t *testing.T) { t.Parallel() res, err := NewValue(tc.str) diff --git a/pkg/label/selector_test.go b/pkg/label/selector_test.go index f764498bec..d80934a7f0 100644 --- a/pkg/label/selector_test.go +++ b/pkg/label/selector_test.go @@ -140,7 +140,6 @@ func TestSelectorMatches(t *testing.T) { } for idx, tc := range cases { - tc := tc t.Run(strconv.Itoa(idx), func(t *testing.T) { t.Parallel() require.Equal(t, tc.shouldMatch, tc.selector.Matches(tc.labels)) @@ -161,13 +160,11 @@ func TestSelectorRegexLazyCompile(t *testing.T) { labelSetNotMatch := map[Key]Value{"tenant": "abcdef", "node_type": "2"} var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 10 { + wg.Go(func() { require.True(t, selector.Matches(labelSetMatch)) require.False(t, selector.Matches(labelSetNotMatch)) - }() + }) } wg.Wait() @@ -235,7 +232,6 @@ func TestSelectorValidate(t *testing.T) { } for idx, tc := range cases { - tc := tc t.Run(strconv.Itoa(idx), func(t *testing.T) { t.Parallel() tc.checkErr(tc.selector.Validate()) diff --git a/pkg/leakutil/leak_helper_test.go b/pkg/leakutil/leak_helper_test.go index 940cc065cb..622f49a7b3 100644 --- a/pkg/leakutil/leak_helper_test.go +++ b/pkg/leakutil/leak_helper_test.go @@ -20,7 +20,7 @@ import ( ) func TestSetUpLeakTest(t *testing.T) { - leakChan := make(chan interface{}) + leakChan := make(chan any) go func() { <-leakChan diff --git a/pkg/logutil/log.go b/pkg/logutil/log.go index 5ac1c6bf55..3539cde8f4 100644 --- a/pkg/logutil/log.go +++ b/pkg/logutil/log.go @@ -18,6 +18,7 @@ import ( "context" "io" "os" + "slices" "strconv" "strings" @@ -202,10 +203,8 @@ func initOptionalComponent(op *loggerOp, cfg *Config) error { // ZapErrorFilter wraps zap.Error, if err is in given filterErrors, it will be set to nil func ZapErrorFilter(err error, filterErrors ...error) zap.Field { cause := errors.Cause(err) - for _, ferr := range filterErrors { - if cause == ferr { - return zap.Error(nil) - } + if slices.Contains(filterErrors, cause) { + return zap.Error(nil) } return zap.Error(err) } diff --git a/pkg/logutil/log_test.go b/pkg/logutil/log_test.go index 479c8240fd..f4ec4cf4b7 100644 --- a/pkg/logutil/log_test.go +++ b/pkg/logutil/log_test.go @@ -220,14 +220,12 @@ func TestMySQLLogger(t *testing.T) { ms, err := net.Listen("tcp4", "127.0.0.1:0") require.NoError(t, err) wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { conn, err := ms.Accept() require.NoError(t, err) err = conn.Close() require.NoError(t, err) - }() + }) dsnStr := fmt.Sprintf("root:@tcp(%s)/", ms.Addr().String()) db, err := sql.Open("mysql", dsnStr) diff --git a/pkg/migrate/migrate_test.go b/pkg/migrate/migrate_test.go index 2c7ade910c..c559aede60 100644 --- a/pkg/migrate/migrate_test.go +++ b/pkg/migrate/migrate_test.go @@ -191,23 +191,17 @@ func TestMigration(t *testing.T) { // 3. tow non-owner node wait for meta migrating done wg := new(sync.WaitGroup) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := migrator.WaitMetaVersionMatched(ctx) require.NoError(t, err) - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { err := migrator.WaitMetaVersionMatched(ctx) require.NoError(t, err) - }() + }) - wg.Add(1) // 4.owner note migrates meta data - go func() { - defer wg.Done() + wg.Go(func() { // 5. test ShouldMigrate works as expected should, err := migrator.ShouldMigrate(ctx) require.NoError(t, err) @@ -216,7 +210,7 @@ func TestMigration(t *testing.T) { err = migrator.Migrate(ctx) require.NoError(t, err) } - }() + }) // 6. wait for migration done wg.Wait() @@ -291,7 +285,7 @@ func TestMigration(t *testing.T) { require.Equal(t, int64(1), v) // migrate again - for i := 0; i < 10; i++ { + for range 10 { err = m.Migrate(ctx) require.Nil(t, err) } @@ -410,23 +404,17 @@ func TestMigrationNonDefaultCluster(t *testing.T) { } // 3. tow non-owner node wait for meta migrating done wg := new(sync.WaitGroup) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := migrator.WaitMetaVersionMatched(ctx) require.NoError(t, err) - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { err := migrator.WaitMetaVersionMatched(ctx) require.NoError(t, err) - }() + }) - wg.Add(1) // 4.owner note migrates meta data - go func() { - defer wg.Done() + wg.Go(func() { // 5. test ShouldMigrate works as expected should, err := migrator.ShouldMigrate(ctx) require.NoError(t, err) @@ -435,7 +423,7 @@ func TestMigrationNonDefaultCluster(t *testing.T) { err = migrator.Migrate(ctx) require.NoError(t, err) } - }() + }) // 6. wait for migration done wg.Wait() @@ -498,8 +486,7 @@ func newMockPDClient(normal bool) *mockPDClient { } func TestMigrateGcServiceSafePoint(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() m := &migrator{} mockClient := newMockPDClient(true) @@ -549,8 +536,7 @@ func TestMigrateGcServiceSafePoint(t *testing.T) { } func TestRemoveOldGcServiceSafePointFailed(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockClient := newMockPDClient(true) m := &migrator{} @@ -589,8 +575,7 @@ func TestRemoveOldGcServiceSafePointFailed(t *testing.T) { } func TestListServiceSafePointFailed(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockClient := newMockPDClient(true) m := &migrator{} @@ -600,8 +585,7 @@ func TestListServiceSafePointFailed(t *testing.T) { } func TestNoServiceSafePoint(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockClient := newMockPDClient(true) m := &migrator{} diff --git a/pkg/notify/notify_test.go b/pkg/notify/notify_test.go index f64f2a232f..2704c6991b 100644 --- a/pkg/notify/notify_test.go +++ b/pkg/notify/notify_test.go @@ -36,7 +36,7 @@ func TestNotifyHub(t *testing.T) { require.Nil(t, err) finishedCh := make(chan struct{}) go func() { - for i := 0; i < 5; i++ { + for range 5 { time.Sleep(time.Second) notifier.Notify() } @@ -82,11 +82,11 @@ func TestContinusStop(t *testing.T) { n := 50 receivers := make([]*Receiver, n) var err error - for i := 0; i < n; i++ { + for i := range n { receivers[i], err = notifier.NewReceiver(10 * time.Millisecond) require.Nil(t, err) } - for i := 0; i < n; i++ { + for i := range n { i := i go func() { for { @@ -98,7 +98,7 @@ func TestContinusStop(t *testing.T) { } }() } - for i := 0; i < n; i++ { + for i := range n { receivers[i].Stop() } <-ctx.Done() @@ -122,9 +122,7 @@ func TestNotifierMultiple(t *testing.T) { counter := atomic.NewInt32(0) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { _, ok := <-receiver.C if !ok { @@ -132,15 +130,13 @@ func TestNotifierMultiple(t *testing.T) { } counter.Add(1) } - }() + }) receiver1, err := notifier.NewReceiver(time.Minute) require.NoError(t, err) counter1 := atomic.NewInt32(0) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { _, ok := <-receiver1.C if !ok { @@ -148,10 +144,10 @@ func TestNotifierMultiple(t *testing.T) { } counter1.Add(1) } - }() + }) N := 5 - for i := 0; i < N; i++ { + for range N { notifier.Notify() time.Sleep(time.Millisecond * 100) } diff --git a/pkg/orchestrator/batch.go b/pkg/orchestrator/batch.go index 3bc9870616..71cd611e57 100644 --- a/pkg/orchestrator/batch.go +++ b/pkg/orchestrator/batch.go @@ -14,6 +14,8 @@ package orchestrator import ( + "maps" + "github.com/pingcap/errors" cerrors "github.com/pingcap/tiflow/pkg/errors" "github.com/pingcap/tiflow/pkg/orchestrator/util" @@ -60,9 +62,7 @@ func getBatchChangedState(state map[util.EtcdKey][]byte, patchGroups [][]DataPat len(batchChangedState)+len(changedState) >= etcdTxnMaxOps { break } - for k, v := range changedState { - batchChangedState[k] = v - } + maps.Copy(batchChangedState, changedState) num++ totalSize += changedSize } diff --git a/pkg/orchestrator/batch_test.go b/pkg/orchestrator/batch_test.go index 95a7721872..d1833bdde8 100644 --- a/pkg/orchestrator/batch_test.go +++ b/pkg/orchestrator/batch_test.go @@ -25,12 +25,12 @@ func TestGetBatchChangeState(t *testing.T) { t.Parallel() patchGroupSize := 1000 patchGroup := make([][]DataPatch, patchGroupSize) - for i := 0; i < patchGroupSize; i++ { + for i := range patchGroupSize { i := i patches := []DataPatch{&SingleDataPatch{ Key: util.NewEtcdKey(fmt.Sprintf("/key%d", i)), Func: func(old []byte) (newValue []byte, changed bool, err error) { - newValue = []byte(fmt.Sprintf("abc%d", i)) + newValue = fmt.Appendf(nil, "abc%d", i) return newValue, true, nil }, }} @@ -42,7 +42,7 @@ func TestGetBatchChangeState(t *testing.T) { require.LessOrEqual(t, n, len(patchGroup)) require.LessOrEqual(t, size, etcdTxnMaxSize) require.LessOrEqual(t, len(changedState), etcdTxnMaxOps) - require.Equal(t, []byte(fmt.Sprintf("abc%d", 0)), changedState[util.NewEtcdKey("/key0")]) + require.Equal(t, fmt.Appendf(nil, "abc%d", 0), changedState[util.NewEtcdKey("/key0")]) // test single patch exceed txn max size largeSizePatches := []DataPatch{&SingleDataPatch{ @@ -63,7 +63,7 @@ func TestGetBatchChangeState(t *testing.T) { manyOpsPatches = append(manyOpsPatches, &SingleDataPatch{ Key: util.NewEtcdKey(fmt.Sprintf("/key%d", i)), Func: func(old []byte) (newValue []byte, changed bool, err error) { - newValue = []byte(fmt.Sprintf("abc%d", i)) + newValue = fmt.Appendf(nil, "abc%d", i) return newValue, true, nil }, }) diff --git a/pkg/orchestrator/etcd_worker_bank_test.go b/pkg/orchestrator/etcd_worker_bank_test.go index 81438e7f02..e6d03ec569 100644 --- a/pkg/orchestrator/etcd_worker_bank_test.go +++ b/pkg/orchestrator/etcd_worker_bank_test.go @@ -92,7 +92,7 @@ func (b *bankReactorState) patchAccount(index int, fn func(int) int) DataPatch { } func (b *bankReactorState) TransferRandomly(transferNumber int) { - for i := 0; i < transferNumber; i++ { + for range transferNumber { accountA := rand.Intn(len(b.account)) accountB := rand.Intn(len(b.account)) transferMoney := rand.Intn(100) @@ -148,16 +148,14 @@ func TestEtcdBank(t *testing.T) { }() defer cancel() - for i := 0; i < totalAccountNumber; i++ { + for i := range totalAccountNumber { _, err := cli.Put(ctx, fmt.Sprintf("%s%d", bankTestPrefix, i), "0") require.Nil(t, err) } - for i := 0; i < workerNumber; i++ { + for i := range workerNumber { i := i - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { worker, err := NewEtcdWorker(cdcCli, bankTestPrefix, &bankReactor{ accountNumber: totalAccountNumber, @@ -171,7 +169,7 @@ func TestEtcdBank(t *testing.T) { require.Contains(t, err.Error(), "context deadline exceeded") return } - }() + }) } wg.Wait() } diff --git a/pkg/orchestrator/etcd_worker_test.go b/pkg/orchestrator/etcd_worker_test.go index 95c49907b0..8623f667e0 100644 --- a/pkg/orchestrator/etcd_worker_test.go +++ b/pkg/orchestrator/etcd_worker_test.go @@ -228,13 +228,13 @@ func TestEtcdSum(t *testing.T) { jsonStr, err := json.Marshal(initArray) require.Nil(t, err) - for i := 0; i < numGroups; i++ { + for i := range numGroups { _, err := cli.Put(ctx, testEtcdKeyPrefix+"/"+strconv.Itoa(i), string(jsonStr)) require.Nil(t, err) } errg, ctx := errgroup.WithContext(ctx) - for i := 0; i < numValuesPerGroup+1; i++ { + for i := range numValuesPerGroup + 1 { finalI := i errg.Go(func() error { values := make([][]int, numGroups) @@ -340,7 +340,7 @@ func TestLinearizability(t *testing.T) { cdcCli, err := etcd.NewCDCEtcdClient(ctx, cli0.Unwrap(), "default") require.Nil(t, err) cli := newClient() - for i := 0; i < 1000; i++ { + for i := range 1000 { _, err := cli.Put(ctx, testEtcdKeyPrefix+"/lin", strconv.Itoa(i)) require.Nil(t, err) } @@ -743,12 +743,10 @@ func TestModifyAfterDelete(t *testing.T) { require.Nil(t, err) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := worker1.Run(ctx, nil, time.Millisecond*100, "owner") require.Nil(t, err) - }() + }) modifyReactor.waitOnCh <- struct{}{} diff --git a/pkg/orchestrator/reactor_state.go b/pkg/orchestrator/reactor_state.go index ccbde53e1c..6571288cb3 100644 --- a/pkg/orchestrator/reactor_state.go +++ b/pkg/orchestrator/reactor_state.go @@ -50,10 +50,7 @@ type GlobalReactorState struct { // NewGlobalState creates a new global state. func NewGlobalState(clusterID string, captureSessionTTL int) *GlobalReactorState { - captureRemoveTTL := captureSessionTTL / 2 - if captureRemoveTTL < defaultCaptureRemoveTTL { - captureRemoveTTL = defaultCaptureRemoveTTL - } + captureRemoveTTL := max(captureSessionTTL/2, defaultCaptureRemoveTTL) return &GlobalReactorState{ ClusterID: clusterID, Owner: map[string]struct{}{}, @@ -436,7 +433,7 @@ func (s *ChangefeedReactorState) Update(key util.EtcdKey, value []byte, _ bool) // UpdateCDCKey updates the state by a parsed etcd key func (s *ChangefeedReactorState) UpdateCDCKey(key *etcd.CDCKey, value []byte) error { - var e interface{} + var e any switch key.Tp { case etcd.CDCKeyTypeChangefeedInfo: if key.ChangefeedID != s.ID { @@ -557,7 +554,7 @@ func (s *ChangefeedReactorState) PatchInfo(fn func(*model.ChangeFeedInfo) (*mode Tp: etcd.CDCKeyTypeChangefeedInfo, ChangefeedID: s.ID, } - s.patchAny(key.String(), changefeedInfoTPI, func(e interface{}) (interface{}, bool, error) { + s.patchAny(key.String(), changefeedInfoTPI, func(e any) (any, bool, error) { // e == nil means that the key is not exist before this patch if e == nil { return fn(nil) @@ -573,7 +570,7 @@ func (s *ChangefeedReactorState) PatchStatus(fn func(*model.ChangeFeedStatus) (* Tp: etcd.CDCKeyTypeChangeFeedStatus, ChangefeedID: s.ID, } - s.patchAny(key.String(), changefeedStatusTPI, func(e interface{}) (interface{}, bool, error) { + s.patchAny(key.String(), changefeedStatusTPI, func(e any) (any, bool, error) { // e == nil means that the key is not exist before this patch if e == nil { return fn(nil) @@ -590,7 +587,7 @@ func (s *ChangefeedReactorState) PatchTaskPosition(captureID model.CaptureID, fn CaptureID: captureID, ChangefeedID: s.ID, } - s.patchAny(key.String(), taskPositionTPI, func(e interface{}) (interface{}, bool, error) { + s.patchAny(key.String(), taskPositionTPI, func(e any) (any, bool, error) { // e == nil means that the key is not exist before this patch if e == nil { return fn(nil) @@ -605,14 +602,14 @@ var ( changefeedInfoTPI *model.ChangeFeedInfo ) -func (s *ChangefeedReactorState) patchAny(key string, tpi interface{}, fn func(interface{}) (interface{}, bool, error)) { +func (s *ChangefeedReactorState) patchAny(key string, tpi any, fn func(any) (any, bool, error)) { patch := &SingleDataPatch{ Key: util.NewEtcdKey(key), Func: func(v []byte) ([]byte, bool, error) { if s.skipPatchesInThisTick { return v, false, cerrors.ErrEtcdIgnore.GenWithStackByArgs() } - var e interface{} + var e any if v != nil { tp := reflect.TypeOf(tpi) e = reflect.New(tp.Elem()).Interface() diff --git a/pkg/p2p/client.go b/pkg/p2p/client.go index 9b67424d66..1cbad9cd3a 100644 --- a/pkg/p2p/client.go +++ b/pkg/p2p/client.go @@ -30,10 +30,10 @@ type MessageClient interface { Run(ctx context.Context, network string, addr string, receiverID NodeID, credential *security.Credential) (ret error) // SendMessage sends a message of a given topic. It would block if the inner channel is congested. - SendMessage(ctx context.Context, topic Topic, value interface{}) (seq Seq, ret error) + SendMessage(ctx context.Context, topic Topic, value any) (seq Seq, ret error) // TrySendMessage tries to send a message of a given topic. It will return an error if the inner channel is congested. - TrySendMessage(ctx context.Context, topic Topic, value interface{}) (seq Seq, ret error) + TrySendMessage(ctx context.Context, topic Topic, value any) (seq Seq, ret error) // CurrentAck is used to query the latest sequence number for a topic that is acknowledged by the server. // Note: currently only used for test. @@ -87,7 +87,7 @@ func (c *localMessageClient) Run( return nil } -func (c *localMessageClient) SendMessage(ctx context.Context, topic Topic, value interface{}) (Seq, error) { +func (c *localMessageClient) SendMessage(ctx context.Context, topic Topic, value any) (Seq, error) { select { case <-ctx.Done(): return 0, ctx.Err() @@ -98,7 +98,7 @@ func (c *localMessageClient) SendMessage(ctx context.Context, topic Topic, value } } -func (c *localMessageClient) TrySendMessage(ctx context.Context, topic Topic, value interface{}) (Seq, error) { +func (c *localMessageClient) TrySendMessage(ctx context.Context, topic Topic, value any) (Seq, error) { select { case <-ctx.Done(): return 0, ctx.Err() diff --git a/pkg/p2p/client_batch_sender.go b/pkg/p2p/client_batch_sender.go index 3527a77fe6..8070cc0353 100644 --- a/pkg/p2p/client_batch_sender.go +++ b/pkg/p2p/client_batch_sender.go @@ -46,10 +46,7 @@ type grpcClientBatchSender struct { } func newClientBatchSender(stream MessageClientStream, maxEntryCount, maxSizeBytes int) clientBatchSender[MessageEntry] { - sliceCap := maxEntryCount - if sliceCap > maxPreallocBatchSize { - sliceCap = maxPreallocBatchSize - } + sliceCap := min(maxEntryCount, maxPreallocBatchSize) return &grpcClientBatchSender{ stream: stream, buffer: make([]MessageEntry, 0, sliceCap), diff --git a/pkg/p2p/client_batch_sender_test.go b/pkg/p2p/client_batch_sender_test.go index aa035a36b1..89d864c854 100644 --- a/pkg/p2p/client_batch_sender_test.go +++ b/pkg/p2p/client_batch_sender_test.go @@ -14,7 +14,6 @@ package p2p import ( - "context" "fmt" "math" "testing" @@ -25,8 +24,7 @@ import ( ) func TestClientBatchSenderMaxCount(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() grpcStream := newMockSendMessageClient(ctx) sender := newClientBatchSender(grpcStream, 100, math.MaxInt64) @@ -36,7 +34,7 @@ func TestClientBatchSenderMaxCount(t *testing.T) { for i := 1; i < 100; i++ { err := sender.Append(&proto.MessageEntry{ Topic: "test-topic", - Content: []byte(fmt.Sprintf("test-%d", i)), + Content: fmt.Appendf(nil, "test-%d", i), Sequence: int64(i), }) require.NoError(t, err) @@ -61,8 +59,7 @@ func TestClientBatchSenderMaxCount(t *testing.T) { } func TestClientBatchSenderMaxSize(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() grpcStream := newMockSendMessageClient(ctx) sender := newClientBatchSender(grpcStream, math.MaxInt64, 1000) @@ -72,7 +69,7 @@ func TestClientBatchSenderMaxSize(t *testing.T) { for size := 0; size < 220; { msg := &proto.MessageEntry{ Topic: "test-topic", - Content: []byte(fmt.Sprintf("test-%d", i)), + Content: fmt.Appendf(nil, "test-%d", i), Sequence: int64(i), } i++ @@ -93,15 +90,14 @@ func TestClientBatchSenderMaxSize(t *testing.T) { // one more message err := sender.Append(&proto.MessageEntry{ Topic: "test-topic", - Content: []byte(fmt.Sprintf("test-%d", i)), + Content: fmt.Appendf(nil, "test-%d", i), Sequence: int64(i), }) require.NoError(t, err) } func TestClientBatchSenderFlush(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() grpcStream := newMockSendMessageClient(ctx) sender := newClientBatchSender(grpcStream, math.MaxInt64, 1000) diff --git a/pkg/p2p/client_connector_test.go b/pkg/p2p/client_connector_test.go index 1777f707cf..1260f1dcbe 100644 --- a/pkg/p2p/client_connector_test.go +++ b/pkg/p2p/client_connector_test.go @@ -52,11 +52,9 @@ func TestClientConnector(t *testing.T) { p2p.RegisterCDCPeerToPeerServer(grpcServer, mockService) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = grpcServer.Serve(lis) - }() + }) cc := newClientConnector() diff --git a/pkg/p2p/grpc_client.go b/pkg/p2p/grpc_client.go index a926d11b18..d8d46cd5b7 100644 --- a/pkg/p2p/grpc_client.go +++ b/pkg/p2p/grpc_client.go @@ -15,6 +15,7 @@ package p2p import ( "context" + "maps" "sync" "time" @@ -251,9 +252,7 @@ func (c *grpcMessageClient) runTx(ctx context.Context, stream MessageClientStrea func (c *grpcMessageClient) retrySending(ctx context.Context, stream MessageClientStream) error { topicsCloned := make(map[string]*topicEntry) c.topicMu.RLock() - for k, v := range c.topics { - topicsCloned[k] = v - } + maps.Copy(topicsCloned, c.topics) c.topicMu.RUnlock() batcher := c.newSenderFn(stream) @@ -355,13 +354,13 @@ func (c *grpcMessageClient) runRx(ctx context.Context, stream MessageClientStrea // SendMessage sends a message. It will block if the client is not ready to // accept the message for now. Once the function returns without an error, // the client will try its best to send the message, until `Run` is canceled. -func (c *grpcMessageClient) SendMessage(ctx context.Context, topic Topic, value interface{}) (seq Seq, ret error) { +func (c *grpcMessageClient) SendMessage(ctx context.Context, topic Topic, value any) (seq Seq, ret error) { return c.sendMessage(ctx, topic, value, false) } // TrySendMessage tries to send a message. It will return ErrPeerMessageSendTryAgain // if the client is not ready to accept the message. -func (c *grpcMessageClient) TrySendMessage(ctx context.Context, topic Topic, value interface{}) (seq Seq, ret error) { +func (c *grpcMessageClient) TrySendMessage(ctx context.Context, topic Topic, value any) (seq Seq, ret error) { // FIXME (zixiong): This is a temporary way for testing client congestion. // This failpoint will be removed once we abstract the MessageClient as an interface. failpoint.Inject("ClientInjectSendMessageTryAgain", func() { @@ -376,7 +375,7 @@ func (c *grpcMessageClient) TrySendMessage(ctx context.Context, topic Topic, val return c.sendMessage(ctx, topic, value, true) } -func (c *grpcMessageClient) sendMessage(ctx context.Context, topic Topic, value interface{}, nonblocking bool) (seq Seq, ret error) { +func (c *grpcMessageClient) sendMessage(ctx context.Context, topic Topic, value any, nonblocking bool) (seq Seq, ret error) { if c.isClosed.Load() { return 0, cerrors.ErrPeerMessageClientClosed.GenWithStackByArgs() } diff --git a/pkg/p2p/grpc_client_test.go b/pkg/p2p/grpc_client_test.go index 378b82a1a9..4cc8e66f4a 100644 --- a/pkg/p2p/grpc_client_test.go +++ b/pkg/p2p/grpc_client_test.go @@ -113,13 +113,11 @@ func TestMessageClientBasics(t *testing.T) { grpcStream.On("Recv").Return(nil, nil) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "", "", "node-2", &security.Credential{}) require.Error(t, err) require.Regexp(t, "context canceled", err.Error()) - }() + }) // wait for the stream meta to be received require.Eventuallyf(t, func() bool { @@ -263,13 +261,11 @@ func TestClientPermanentFailure(t *testing.T) { }, nil) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "", "", "node-2", &security.Credential{}) require.Error(t, err) require.Regexp(t, ".*ErrPeerMessageClientPermanentFail.*", err.Error()) - }() + }) wg.Wait() @@ -324,13 +320,11 @@ func TestClientSendAnomalies(t *testing.T) { sender.On("Append", mock.Anything).Return(nil) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(runCtx, "", "", "node-2", &security.Credential{}) require.Error(t, err) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) // Test point 1: ErrPeerMessageSendTryAgain _, err := client.TrySendMessage(ctx, "test-topic", &testMessage{Value: 1}) diff --git a/pkg/p2p/internal/send_chan_test.go b/pkg/p2p/internal/send_chan_test.go index f35d4814ba..c7e1dab0a0 100644 --- a/pkg/p2p/internal/send_chan_test.go +++ b/pkg/p2p/internal/send_chan_test.go @@ -40,10 +40,8 @@ func TestSendChanBasics(t *testing.T) { var wg sync.WaitGroup // Runs the producers - for i := 0; i < numProducers; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range numProducers { + wg.Go(func() { lastSeq := int64(0) for j := 0; j < numMsgPerProducer; { ok, seq := c.SendAsync( @@ -59,13 +57,11 @@ func TestSendChanBasics(t *testing.T) { require.Greater(t, seq, lastSeq) lastSeq = seq } - }() + }) } // Runs the consumer - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { ticker := time.NewTicker(time.Millisecond * 10) recvCount := 0 @@ -83,7 +79,7 @@ func TestSendChanBasics(t *testing.T) { return } } - }() + }) wg.Wait() cancel() @@ -101,12 +97,10 @@ func TestSendChanSendSync(t *testing.T) { var wg sync.WaitGroup // Runs the producers - for i := 0; i < numProducers; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range numProducers { + wg.Go(func() { lastSeq := int64(0) - for j := 0; j < numMsgPerProducerForSync; j++ { + for range numMsgPerProducerForSync { seq, err := c.SendSync( ctx, "test-topic", @@ -119,13 +113,11 @@ func TestSendChanSendSync(t *testing.T) { require.Greater(t, seq, lastSeq) lastSeq = seq } - }() + }) } // Runs the consumer - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { ticker := time.NewTicker(time.Millisecond * 10) recvCount := 0 @@ -143,7 +135,7 @@ func TestSendChanSendSync(t *testing.T) { return } } - }() + }) wg.Wait() cancel() @@ -155,9 +147,7 @@ func BenchmarkSendChanSendAsyncSPSC(b *testing.B) { seq := atomic.NewInt64(0) c := NewSendChan(defaultSendChanCap) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for j := 0; j < b.N; { ok, _ := c.SendAsync("test-topic", []byte("test-value"), func() int64 { return seq.Inc() @@ -167,7 +157,7 @@ func BenchmarkSendChanSendAsyncSPSC(b *testing.B) { } j++ } - }() + }) recvCount := 0 dummyTicker := make(chan time.Time) @@ -196,9 +186,7 @@ func BenchmarkSendChanSendSyncSPSC(b *testing.B) { seq := atomic.NewInt64(0) c := NewSendChan(defaultSendChanCap) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for j := 0; j < b.N; j++ { _, _ = c.SendSync( context.TODO(), @@ -208,7 +196,7 @@ func BenchmarkSendChanSendSyncSPSC(b *testing.B) { return seq.Inc() }) } - }() + }) recvCount := 0 dummyTicker := make(chan time.Time) @@ -235,10 +223,8 @@ func BenchmarkSendChanSendAsyncMPSC8(b *testing.B) { seq := atomic.NewInt64(0) c := NewSendChan(defaultSendChanCap) - for i := 0; i < 8; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 8 { + wg.Go(func() { for j := 0; j < b.N; { ok, _ := c.SendAsync("test-topic", []byte("test-value"), func() int64 { return seq.Inc() @@ -248,7 +234,7 @@ func BenchmarkSendChanSendAsyncMPSC8(b *testing.B) { } j++ } - }() + }) } recvCount := 0 @@ -277,10 +263,8 @@ func BenchmarkSendChanSendSyncMPSC8(b *testing.B) { c := NewSendChan(defaultSendChanCap) dummyCloseCh := make(chan struct{}) - for i := 0; i < 8; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for range 8 { + wg.Go(func() { for j := 0; j < b.N; j++ { _, _ = c.SendSync( context.TODO(), @@ -290,7 +274,7 @@ func BenchmarkSendChanSendSyncMPSC8(b *testing.B) { return seq.Inc() }) } - }() + }) } recvCount := 0 diff --git a/pkg/p2p/message_router.go b/pkg/p2p/message_router.go index 6178bb73e2..3276a424e0 100644 --- a/pkg/p2p/message_router.go +++ b/pkg/p2p/message_router.go @@ -171,9 +171,7 @@ func (m *messageRouterImpl) GetClient(target NodeID) MessageClient { MessageClient: client, cancelFn: cancel, } - m.wg.Add(1) - go func() { - defer m.wg.Done() + m.wg.Go(func() { defer cancel() err := client.Run(ctx, "tcp", addr, target, m.credentials) if err != nil { @@ -198,7 +196,7 @@ func (m *messageRouterImpl) GetClient(target NodeID) MessageClient { m.mu.Lock() defer m.mu.Unlock() delete(m.clients, target) - }() + }) } m.clients[target] = cliWrapper diff --git a/pkg/p2p/message_router_test.go b/pkg/p2p/message_router_test.go index 355c92c9ff..359b964fcd 100644 --- a/pkg/p2p/message_router_test.go +++ b/pkg/p2p/message_router_test.go @@ -78,22 +78,18 @@ func (s *messageRouterTestSuite) addServer(ctx context.Context, t *testing.T, id s.messageRouter.AddPeer(id, addr) - s.wg.Add(1) - go func() { - defer s.wg.Done() + s.wg.Go(func() { _ = grpcServer.Serve(lis) - }() + }) - s.wg.Add(1) - go func() { - defer s.wg.Done() + s.wg.Go(func() { defer grpcServer.Stop() defer s.messageRouter.RemovePeer(id) err := newServer.Run(ctx, nil) if err != nil { require.Regexp(t, ".*context canceled.*", err.Error()) } - }() + }) } func (s *messageRouterTestSuite) close() { @@ -123,7 +119,7 @@ func TestMessageRouterBasic(t *testing.T) { require.Nilf(t, noClient, "no client should have been created") var lastIndex [3]int64 - mustAddHandler(ctx, t, suite.getServer("server-1"), "test-topic", &testTopicContent{}, func(senderID string, i interface{}) error { + mustAddHandler(ctx, t, suite.getServer("server-1"), "test-topic", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -132,7 +128,7 @@ func TestMessageRouterBasic(t *testing.T) { return nil }) - mustAddHandler(ctx, t, suite.getServer("server-2"), "test-topic", &testTopicContent{}, func(senderID string, i interface{}) error { + mustAddHandler(ctx, t, suite.getServer("server-2"), "test-topic", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -141,7 +137,7 @@ func TestMessageRouterBasic(t *testing.T) { return nil }) - mustAddHandler(ctx, t, suite.getServer("server-3"), "test-topic", &testTopicContent{}, func(senderID string, i interface{}) error { + mustAddHandler(ctx, t, suite.getServer("server-3"), "test-topic", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -151,7 +147,7 @@ func TestMessageRouterBasic(t *testing.T) { }) var lastSeq [3]Seq - for i := 0; i < defaultMessageBatchSizeLarge; i++ { + for i := range defaultMessageBatchSizeLarge { serverIdx := i % 3 serverID := fmt.Sprintf("server-%d", serverIdx+1) Seq, err := suite.messageRouter.GetClient(serverID).SendMessage(ctx, "test-topic", &testTopicContent{int64(i/3) + 1}) @@ -197,7 +193,7 @@ func TestMessageRouterRemovePeer(t *testing.T) { suite.addServer(ctx, t, "server-2") var lastIndex [3]int64 - mustAddHandler(ctx, t, suite.getServer("server-1"), "test-topic", &testTopicContent{}, func(senderID string, i interface{}) error { + mustAddHandler(ctx, t, suite.getServer("server-1"), "test-topic", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -206,7 +202,7 @@ func TestMessageRouterRemovePeer(t *testing.T) { return nil }) - mustAddHandler(ctx, t, suite.getServer("server-2"), "test-topic", &testTopicContent{}, func(senderID string, i interface{}) error { + mustAddHandler(ctx, t, suite.getServer("server-2"), "test-topic", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -216,11 +212,9 @@ func TestMessageRouterRemovePeer(t *testing.T) { }) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { var lastSeq Seq - for i := 0; i < defaultMessageBatchSizeLarge; i++ { + for i := range defaultMessageBatchSizeLarge { var err error lastSeq, err = suite.messageRouter.GetClient("server-1"). SendMessage(ctx, "test-topic", &testTopicContent{int64(i + 1)}) @@ -233,14 +227,12 @@ func TestMessageRouterRemovePeer(t *testing.T) { } return seq >= lastSeq }, time.Second*10, time.Millisecond*20) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { client := suite.messageRouter.GetClient("server-2") require.NotNil(t, client) - for i := 0; i < defaultMessageBatchSizeSmall; i++ { + for i := range defaultMessageBatchSizeSmall { var err error _, err = client.SendMessage(ctx, "test-topic", &testTopicContent{int64(i + 1)}) require.NoError(t, err) @@ -253,7 +245,7 @@ func TestMessageRouterRemovePeer(t *testing.T) { return err != nil }, time.Millisecond*500, time.Millisecond*50) require.Regexp(t, ".*ErrPeerMessageClientClosed.*", err.Error()) - }() + }) wg.Wait() suite.close() diff --git a/pkg/p2p/mock_cluster.go b/pkg/p2p/mock_cluster.go index 1c9a28c1ae..3aa2fde44e 100644 --- a/pkg/p2p/mock_cluster.go +++ b/pkg/p2p/mock_cluster.go @@ -85,28 +85,22 @@ func newMockNode(t *testing.T, id NodeID) *MockNode { grpcServer := grpc.NewServer() proto.RegisterCDCPeerToPeerServer(grpcServer, ret.Server) - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { lis, err := net.Listen("tcp", addr) require.NoError(t, err) _ = grpcServer.Serve(lis) - }() + }) - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { err := ret.Server.Run(ctx, nil) require.Error(t, err) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) - ret.wg.Add(1) - go func() { - defer ret.wg.Done() + ret.wg.Go(func() { <-ctx.Done() grpcServer.Stop() - }() + }) return ret } @@ -124,7 +118,7 @@ func NewMockCluster(t *testing.T, nodeCount int) *MockCluster { Nodes: make(map[NodeID]*MockNode), } - for i := 0; i < nodeCount; i++ { + for i := range nodeCount { id := fmt.Sprintf("capture-%d", i) ret.Nodes[id] = newMockNode(t, id) } diff --git a/pkg/p2p/model.go b/pkg/p2p/model.go index 0de5676421..71c42e17fd 100644 --- a/pkg/p2p/model.go +++ b/pkg/p2p/model.go @@ -37,5 +37,5 @@ type MessageEntry = *proto.MessageEntry // RawMessageEntry is an alias for the protobuf-generated type for a message. type RawMessageEntry struct { topic Topic - value interface{} + value any } diff --git a/pkg/p2p/serializer.go b/pkg/p2p/serializer.go index bf787c6fad..aa43721896 100644 --- a/pkg/p2p/serializer.go +++ b/pkg/p2p/serializer.go @@ -22,14 +22,14 @@ type Serializable interface { Unmarshal(data []byte) error } -func marshalMessage(value interface{}) ([]byte, error) { +func marshalMessage(value any) ([]byte, error) { if value, ok := value.(Serializable); ok { return value.Marshal() } return json.Marshal(value) } -func unmarshalMessage(data []byte, value interface{}) error { +func unmarshalMessage(data []byte, value any) error { if value, ok := value.(Serializable); ok { return value.Unmarshal(data) } diff --git a/pkg/p2p/server.go b/pkg/p2p/server.go index 8c88467669..e93106620c 100755 --- a/pkg/p2p/server.go +++ b/pkg/p2p/server.go @@ -150,7 +150,7 @@ type MessageServer struct { // taskQueue is used to store internal tasks MessageServer // needs to execute serially. - taskQueue chan interface{} + taskQueue chan any // The WorkerPool instance used to execute message handlers. pool workerpool.WorkerPool @@ -204,7 +204,7 @@ func NewMessageServer(serverID NodeID, config *MessageServerConfig) *MessageServ peers: make(map[string]*cdcPeer), pendingMessages: make(map[topicSenderPair][]pendingMessageEntry), acks: newAckManager(), - taskQueue: make(chan interface{}, config.MaxPendingTaskCount), + taskQueue: make(chan any, config.MaxPendingTaskCount), pool: workerpool.NewDefaultWorkerPool(config.WorkerPoolSize), closeCh: make(chan struct{}), config: config, @@ -406,7 +406,7 @@ func (m *MessageServer) ScheduleDeregisterPeerTask(ctx context.Context, peerID s // We pass an object of the desired type, and use `reflect.TypeOf` to extract the type, // and then when we need it, we can use `reflect.New` to allocate a new object of this // type. -type typeInformation = interface{} +type typeInformation = any // SyncAddHandler registers a handler for messages in a given topic and waits for the operation // to complete. @@ -414,7 +414,7 @@ func (m *MessageServer) SyncAddHandler( ctx context.Context, topic string, tpi typeInformation, - fn func(string, interface{}) error, + fn func(string, any) error, ) (<-chan error, error) { doneCh, errCh, err := m.AddHandler(ctx, topic, tpi, fn) if err != nil { @@ -435,7 +435,7 @@ func (m *MessageServer) AddHandler( ctx context.Context, topic string, tpi typeInformation, - fn func(string, interface{}) error, + fn func(string, any) error, ) (chan struct{}, <-chan error, error) { tp := reflect.TypeOf(tpi) @@ -443,7 +443,7 @@ func (m *MessageServer) AddHandler( "topic": topic, }) - poolHandle := m.pool.RegisterEvent(func(ctx context.Context, argsI interface{}) error { + poolHandle := m.pool.RegisterEvent(func(ctx context.Context, argsI any) error { args, ok := argsI.(poolEventArgs) if !ok { // Handle message from local. @@ -637,7 +637,7 @@ func (m *MessageServer) registerPeer( return nil } -func (m *MessageServer) scheduleTask(ctx context.Context, task interface{}) error { +func (m *MessageServer) scheduleTask(ctx context.Context, task any) error { select { case <-ctx.Done(): return errors.Trace(ctx.Err()) @@ -648,7 +648,7 @@ func (m *MessageServer) scheduleTask(ctx context.Context, task interface{}) erro return nil } -func (m *MessageServer) scheduleTaskBlocking(ctx context.Context, task interface{}) error { +func (m *MessageServer) scheduleTaskBlocking(ctx context.Context, task any) error { select { case <-ctx.Done(): return errors.Trace(ctx.Err()) diff --git a/pkg/p2p/server_ack_manager.go b/pkg/p2p/server_ack_manager.go index 54789fefa1..7e49adcd33 100644 --- a/pkg/p2p/server_ack_manager.go +++ b/pkg/p2p/server_ack_manager.go @@ -101,7 +101,7 @@ func (m *ackManager) Range(senderID NodeID, fn func(topic Topic, seq Seq) bool) // RemoveTopic removes a topic for all nodes. // We do not support removing a topic from a specific node. func (m *ackManager) RemoveTopic(topic Topic) { - m.peers.Range(func(key, value interface{}) bool { + m.peers.Range(func(key, value any) bool { ackList := value.(*peerAckList) ackList.mu.Lock() defer ackList.mu.Unlock() diff --git a/pkg/p2p/server_client_integration_test.go b/pkg/p2p/server_client_integration_test.go index d0206461c2..3560b94ba1 100644 --- a/pkg/p2p/server_client_integration_test.go +++ b/pkg/p2p/server_client_integration_test.go @@ -65,11 +65,9 @@ func newServerForIntegrationTesting(t *testing.T, serverID string, configOpts .. p2p.RegisterCDCPeerToPeerServer(grpcServer, server) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = grpcServer.Serve(lis) - }() + }) cancel = func() { grpcServer.Stop() @@ -95,9 +93,7 @@ func runP2PIntegrationTest( defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { err := server.Run(ctx, nil) if cerror.ErrPeerMessageInjectedServerRestart.Equal(err) { @@ -107,12 +103,12 @@ func runP2PIntegrationTest( require.Regexp(t, ".*context canceled.*", err.Error()) break } - }() + }) - for j := 0; j < numTopics; j++ { + for j := range numTopics { topicName := fmt.Sprintf("test-topic-%d", j) var lastIndex int64 - errCh := mustAddHandler(ctx, t, server, topicName, &testTopicContent{}, func(senderID string, i interface{}) error { + errCh := mustAddHandler(ctx, t, server, topicName, &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -123,27 +119,23 @@ func runP2PIntegrationTest( return nil }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case <-ctx.Done(): case err := <-errCh: require.NoError(t, err) } - }() + }) } client := NewGrpcMessageClient("test-client-1", clientConfig4Testing) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "tcp", addr, "test-server-1", &security.Credential{}) if err != nil { log.Warn("client returned error", zap.Error(err)) require.Regexp(t, ".*context canceled.*", err.Error()) } - }() + }) var wg1 sync.WaitGroup wg1.Add(numTopics * clientConcurrency) @@ -152,7 +144,7 @@ func runP2PIntegrationTest( go func() { defer wg1.Done() var oldSeq Seq - for i := 0; i < size; i++ { + for i := range size { content := &testTopicContent{Index: int64(i + 1)} seq, err := client.SendMessage(ctx, topicName, content) require.NoError(t, err) @@ -260,17 +252,15 @@ func TestMessageClientBasicNonblocking(t *testing.T) { defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) if err != nil { require.Regexp(t, ".*context canceled.*", err.Error()) } - }() + }) var lastIndex int64 - errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i interface{}) error { + errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -279,27 +269,23 @@ func TestMessageClientBasicNonblocking(t *testing.T) { return nil }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case <-ctx.Done(): case err := <-errCh: require.NoError(t, err) } - }() + }) client := NewGrpcMessageClient("test-client-1", clientConfig4Testing) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "tcp", addr, "test-server-1", &security.Credential{}) require.Error(t, err) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) var oldSeq Seq - for i := 0; i < defaultMessageBatchSizeSmall; i++ { + for i := range defaultMessageBatchSizeSmall { content := &testTopicContent{Index: int64(i + 1)} var ( seq Seq @@ -337,38 +323,32 @@ func TestMessageBackPressure(t *testing.T) { defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) if err != nil { require.Regexp(t, ".*context canceled.*", err.Error()) } - }() + }) // No-op handler. We are only testing for back-pressure. - errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i interface{}) error { + errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i any) error { return nil }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case <-ctx.Done(): case err := <-errCh: require.NoError(t, err) } - }() + }) client := NewGrpcMessageClient("test-client-1", clientConfig4Testing) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "tcp", addr, "test-server-1", &security.Credential{}) require.Error(t, err) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) _ = failpoint.Enable("github.com/pingcap/tiflow/pkg/p2p/ServerInjectTaskDelay", "sleep(1)") defer func() { @@ -376,7 +356,7 @@ func TestMessageBackPressure(t *testing.T) { }() var lastSeq Seq - for i := 0; i < defaultMessageBatchSizeLarge; i++ { + for range defaultMessageBatchSizeLarge { seq, err := client.SendMessage(ctx, "test-topic-1", &testTopicContent{}) require.NoError(t, err) atomic.StoreInt64(&lastSeq, seq) @@ -405,43 +385,37 @@ func TestTopicCongested(t *testing.T) { defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) if err != nil { require.Regexp(t, ".*context canceled.*", err.Error()) } - }() + }) newClientConfig := *clientConfig4Testing newClientConfig.MaxBatchCount = 1 newClientConfig.RetryRateLimitPerSecond = 100 client := NewGrpcMessageClient("test-client-1", clientConfig4Testing) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := client.Run(ctx, "tcp", addr, "test-server-1", &security.Credential{}) require.Error(t, err) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) var lastSeq Seq - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { - for i := 0; i < 100; i++ { + for range 100 { seq, err := client.SendMessage(ctx, "test-topic-1", &testTopicContent{}) require.NoError(t, err) atomic.StoreInt64(&lastSeq, seq) time.Sleep(10 * time.Millisecond) } - }() + }) // No-op handler. _ = mustAddHandler(ctx, t, server, "test-topic-1", - &testTopicContent{}, func(senderID string, i interface{}) error { + &testTopicContent{}, func(senderID string, i any) error { return nil }) @@ -453,7 +427,7 @@ func TestTopicCongested(t *testing.T) { // No-op handler. _ = mustAddHandler(ctx, t, server, "test-topic-1", - &testTopicContent{}, func(senderID string, i interface{}) error { + &testTopicContent{}, func(senderID string, i any) error { return nil }) diff --git a/pkg/p2p/server_stream_handle_test.go b/pkg/p2p/server_stream_handle_test.go index 1034c5811a..a5221e1365 100644 --- a/pkg/p2p/server_stream_handle_test.go +++ b/pkg/p2p/server_stream_handle_test.go @@ -39,12 +39,10 @@ func TestStreamHandleSend(t *testing.T) { defer cancel() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { msg := <-sendCh require.Equal(t, "test", msg.ErrorMessage) - }() + }) err := h.Send(ctx, proto.SendMessageResponse{ ErrorMessage: "test", @@ -68,13 +66,11 @@ func TestStreamHandleCloseWhileSending(t *testing.T) { defer cancel() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := h.Send(ctx, proto.SendMessageResponse{}) require.Error(t, err) require.Regexp(t, "ErrPeerMessageInternalSenderClosed", err.Error()) - }() + }) time.Sleep(100 * time.Millisecond) h.Close() diff --git a/pkg/p2p/server_test.go b/pkg/p2p/server_test.go index 017991e413..ae570c28a5 100644 --- a/pkg/p2p/server_test.go +++ b/pkg/p2p/server_test.go @@ -65,11 +65,9 @@ func newServerForTesting(t *testing.T, serverID string) (server *MessageServer, p2p.RegisterCDCPeerToPeerServer(grpcServer, server) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = grpcServer.Serve(lis) - }() + }) cancel = func() { grpcServer.Stop() @@ -93,7 +91,7 @@ func newServerForTesting(t *testing.T, serverID string) (server *MessageServer, return } -func mustAddHandler(ctx context.Context, t *testing.T, server *MessageServer, topic string, tpi interface{}, f func(string, interface{}) error) <-chan error { +func mustAddHandler(ctx context.Context, t *testing.T, server *MessageServer, topic string, tpi any, f func(string, any) error) <-chan error { doneCh, errCh, err := server.AddHandler(ctx, topic, tpi, f) require.NoError(t, err) @@ -123,15 +121,13 @@ func TestServerMultiClientSingleTopic(t *testing.T) { localCh := make(chan RawMessageEntry, defaultMessageBatchSizeMedium) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, localCh) require.Regexp(t, ".*context canceled.*", err) - }() + }) var ackWg sync.WaitGroup - for i := 0; i < defaultMultiClientCount; i++ { + for i := range defaultMultiClientCount { wg.Add(1) ackWg.Add(1) i := i @@ -170,7 +166,7 @@ func TestServerMultiClientSingleTopic(t *testing.T) { } }() - for j := 0; j < defaultMessageBatchSizeMedium; j++ { + for j := range defaultMessageBatchSizeMedium { content := &testTopicContent{Index: int64(j + 1)} bytes, err := json.Marshal(content) require.NoError(t, err) @@ -192,7 +188,7 @@ func TestServerMultiClientSingleTopic(t *testing.T) { time.Sleep(1 * time.Second) lastIndices := sync.Map{} - errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i interface{}) error { + errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i any) error { if strings.Contains(senderID, "server") { require.Equal(t, serverID, senderID) } else { @@ -216,7 +212,7 @@ func TestServerMultiClientSingleTopic(t *testing.T) { ackWg.Add(1) go func() { defer wg.Done() - for j := 0; j < defaultMessageBatchSizeLarge; j++ { + for j := range defaultMessageBatchSizeLarge { content := &testTopicContent{Index: int64(j + 1)} select { case <-ctx.Done(): @@ -249,16 +245,14 @@ func TestServerMultiClientSingleTopic(t *testing.T) { }() }() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case <-ctx.Done(): case err := <-errCh: require.Error(t, err) require.Regexp(t, ".*ErrWorkerPoolHandleCancelled.*", err.Error()) } - }() + }) ackWg.Wait() @@ -283,18 +277,16 @@ func TestServerDeregisterHandler(t *testing.T) { defer closer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) var ( lastIndex int64 removed int32 ) - errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i interface{}) error { + errCh := mustAddHandler(ctx, t, server, "test-topic-1", &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, int32(0), atomic.LoadInt32(&removed)) require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) @@ -304,15 +296,13 @@ func TestServerDeregisterHandler(t *testing.T) { return nil }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { select { case <-ctx.Done(): case err := <-errCh: require.Regexp(t, ".*ErrWorkerPoolHandleCancelled.*", err.Error()) } - }() + }) client, closeClient := newClient() defer closeClient() @@ -330,9 +320,7 @@ func TestServerDeregisterHandler(t *testing.T) { require.NoError(t, err) removeHandler := func() { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { doneCh, err := server.RemoveHandler(ctx, "test-topic-1") require.NoError(t, err) select { @@ -341,12 +329,10 @@ func TestServerDeregisterHandler(t *testing.T) { case <-doneCh: } atomic.StoreInt32(&removed, 1) - }() + }) } - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer cancel() defer closer() var lastAck int64 @@ -367,9 +353,9 @@ func TestServerDeregisterHandler(t *testing.T) { return } } - }() + }) - for i := 0; i < defaultMessageBatchSizeSmall; i++ { + for i := range defaultMessageBatchSizeSmall { content := &testTopicContent{Index: int64(i + 1)} bytes, err := json.Marshal(content) require.NoError(t, err) @@ -398,12 +384,10 @@ func TestServerClosed(t *testing.T) { cctx, cancelServer := context.WithCancel(ctx) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(cctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) client, closeClient := newClient() defer closeClient() @@ -440,12 +424,10 @@ func TestServerTopicCongestedDueToNoHandler(t *testing.T) { defer closer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) client, closeClient := newClient() defer closeClient() @@ -462,9 +444,7 @@ func TestServerTopicCongestedDueToNoHandler(t *testing.T) { }) require.NoError(t, err) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for { resp, err := stream.Recv() require.NoError(t, err) @@ -475,9 +455,9 @@ func TestServerTopicCongestedDueToNoHandler(t *testing.T) { cancel() return } - }() + }) - for i := 0; i < defaultMessageBatchSizeMedium; i++ { + for i := range defaultMessageBatchSizeMedium { content := &testTopicContent{Index: int64(i + 1)} bytes, err := json.Marshal(content) require.NoError(t, err) @@ -508,12 +488,10 @@ func TestServerIncomingConnectionStale(t *testing.T) { defer closer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) client, closeClient := newClient() defer closeClient() @@ -574,12 +552,10 @@ func TestServerOldConnectionStale(t *testing.T) { defer closer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) client, closeClient := newClient() defer closeClient() @@ -639,16 +615,14 @@ func TestServerRepeatedMessages(t *testing.T) { defer closer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) var lastIndex int64 _ = mustAddHandler(ctx, t, server, "test-topic-1", - &testTopicContent{}, func(senderID string, i interface{}) error { + &testTopicContent{}, func(senderID string, i any) error { require.Equal(t, "test-client-1", senderID) require.IsType(t, &testTopicContent{}, i) content := i.(*testTopicContent) @@ -672,9 +646,7 @@ func TestServerRepeatedMessages(t *testing.T) { }) require.NoError(t, err) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer cancel() for { resp, err := stream.Recv() @@ -690,9 +662,9 @@ func TestServerRepeatedMessages(t *testing.T) { return } } - }() + }) - for i := 0; i < defaultMessageBatchSizeSmall; i++ { + for i := range defaultMessageBatchSizeSmall { content := &testTopicContent{Index: int64(i + 1)} bytes, err := json.Marshal(content) require.NoError(t, err) @@ -740,41 +712,33 @@ func TestServerExitWhileAddingHandler(t *testing.T) { defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(serverCtx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) waitCh := make(chan struct{}) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.scheduleTask(ctx, taskDebugDelay{ doneCh: waitCh, }) require.NoError(t, err) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { time.Sleep(time.Millisecond * 100) - _, err := server.SyncAddHandler(ctx, "test-topic", &testTopicContent{}, func(s string, i interface{}) error { + _, err := server.SyncAddHandler(ctx, "test-topic", &testTopicContent{}, func(s string, i any) error { return nil }) require.Error(t, err) require.Regexp(t, ".*ErrPeerMessageServerClosed.*", err.Error()) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { time.Sleep(time.Millisecond * 300) cancelServer() - }() + }) wg.Wait() } @@ -790,19 +754,15 @@ func TestServerExitWhileRemovingHandler(t *testing.T) { defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(serverCtx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) waitCh := make(chan struct{}) - wg.Add(1) - go func() { - defer wg.Done() - _, err := server.SyncAddHandler(ctx, "test-topic", &testTopicContent{}, func(s string, i interface{}) error { + wg.Go(func() { + _, err := server.SyncAddHandler(ctx, "test-topic", &testTopicContent{}, func(s string, i any) error { return nil }) require.NoError(t, err) @@ -813,14 +773,12 @@ func TestServerExitWhileRemovingHandler(t *testing.T) { time.Sleep(time.Millisecond * 100) err = server.SyncRemoveHandler(ctx, "test-topic") require.NoError(t, err) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { time.Sleep(time.Millisecond * 500) cancelServer() - }() + }) wg.Wait() } @@ -833,12 +791,10 @@ func TestReceiverIDMismatch(t *testing.T) { defer closer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) client, closeClient := newClient() defer closeClient() @@ -874,15 +830,13 @@ func TestServerDataLossAfterUnregisterHandle(t *testing.T) { defer cancelServer() var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(serverCtx, nil) require.Regexp(t, ".*context canceled.*", err.Error()) - }() + }) var called int32 - mustAddHandler(ctx, t, server, "blocking-handler", &testTopicContent{}, func(_ string, _ interface{}) error { + mustAddHandler(ctx, t, server, "blocking-handler", &testTopicContent{}, func(_ string, _ any) error { if atomic.AddInt32(&called, 1) == 2 { time.Sleep(1 * time.Second) } @@ -934,7 +888,7 @@ func TestServerDataLossAfterUnregisterHandle(t *testing.T) { require.NoError(t, err) // re-registers the handler - errCh := mustAddHandler(ctx, t, server, "blocking-handler", &testTopicContent{}, func(_ string, msg interface{}) error { + errCh := mustAddHandler(ctx, t, server, "blocking-handler", &testTopicContent{}, func(_ string, msg any) error { require.Fail(t, "should not have been called", "value: %v", msg) return nil }) @@ -975,12 +929,10 @@ func TestServerDeregisterPeer(t *testing.T) { server.config.MaxPendingMessageCountPerTopic = math.MaxInt64 var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx, nil) require.Regexp(t, ".*context canceled.*", err) - }() + }) var sendGroup sync.WaitGroup sendGroup.Add(1) diff --git a/pkg/p2p/server_wrapper_test.go b/pkg/p2p/server_wrapper_test.go index af517ab24f..cd7111a491 100644 --- a/pkg/p2p/server_wrapper_test.go +++ b/pkg/p2p/server_wrapper_test.go @@ -75,11 +75,9 @@ func newServerWrapperForTesting(t *testing.T) (server *ServerWrapper, newClient p2p.RegisterCDCPeerToPeerServer(grpcServer, server) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { _ = grpcServer.Serve(lis) - }() + }) cancel = func() { grpcServer.Stop() diff --git a/pkg/pdutil/api_client_test.go b/pkg/pdutil/api_client_test.go index 2331d9b4e5..6c3c703cde 100644 --- a/pkg/pdutil/api_client_test.go +++ b/pkg/pdutil/api_client_test.go @@ -68,8 +68,7 @@ func TestMetaLabelNormal(t *testing.T) { require.NoError(t, err) defer pc.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() err = pc.UpdateMetaLabel(ctx) require.NoError(t, err) mockClient.testServer.Close() @@ -84,8 +83,7 @@ func TestMetaLabelFail(t *testing.T) { defer pc.Close() mockClient.url = "http://127.0.1.1:2345" - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // test url error err = pc.(*pdAPIClient).patchMetaLabel(ctx) require.Error(t, err) @@ -105,8 +103,7 @@ func TestListGcServiceSafePoint(t *testing.T) { mockClient := newMockPDClient(true) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() pc, err := NewPDAPIClient(mockClient, nil) require.NoError(t, err) @@ -132,7 +129,7 @@ type LabelRule struct { Index int `json:"index"` Labels []RegionLabel `json:"labels"` RuleType string `json:"rule_type"` - Data interface{} `json:"data"` + Data any `json:"data"` } // RegionLabel is the label of a region. @@ -149,7 +146,7 @@ func TestMetaLabelDecodeJSON(t *testing.T) { meta := LabelRulePatch{} require.Nil(t, json.Unmarshal([]byte(addMetaJSON), &meta)) require.Len(t, meta.SetRules, 2) - keys := meta.SetRules[1].Data.([]interface{})[0].(map[string]interface{}) + keys := meta.SetRules[1].Data.([]any)[0].(map[string]any) startKey, err := hex.DecodeString(keys["start_key"].(string)) require.NoError(t, err) endKey, err := hex.DecodeString(keys["end_key"].(string)) diff --git a/pkg/pdutil/clock_test.go b/pkg/pdutil/clock_test.go index 57f7c56360..8d9cf8c61b 100644 --- a/pkg/pdutil/clock_test.go +++ b/pkg/pdutil/clock_test.go @@ -55,8 +55,7 @@ func TestTimeFromPD(t *testing.T) { func TestEventTimeAndProcessingTime(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() mockPDClient := &MockPDClient{} clock, err := NewClock(ctx, mockPDClient) require.NoError(t, err) diff --git a/pkg/retry/retry_test.go b/pkg/retry/retry_test.go index 2080e7cb34..8a36a05807 100644 --- a/pkg/retry/retry_test.go +++ b/pkg/retry/retry_test.go @@ -148,7 +148,7 @@ func TestDoCornerCases(t *testing.T) { require.Equal(t, callCount, 2) var i uint64 - for i = 0; i < 10; i++ { + for i = range 10 { callCount = 0 err = Do(context.Background(), f, WithBackoffBaseDelay(int64(i)), WithBackoffMaxDelay(int64(i)), WithMaxTries(i)) diff --git a/pkg/security/credential.go b/pkg/security/credential.go index ef454bacb6..ea507f411d 100644 --- a/pkg/security/credential.go +++ b/pkg/security/credential.go @@ -54,7 +54,7 @@ func (s Credential) Value() (driver.Value, error) { } // Scan implements the sql.Scanner interface -func (s *Credential) Scan(value interface{}) error { +func (s *Credential) Scan(value any) error { b, ok := value.([]byte) if !ok { return errors.New("type assertion to []byte failed") diff --git a/pkg/security/sasl_test.go b/pkg/security/sasl_test.go index ad8546965b..71f3c90754 100644 --- a/pkg/security/sasl_test.go +++ b/pkg/security/sasl_test.go @@ -76,7 +76,6 @@ func TestSASLMechanismFromString(t *testing.T) { }, } for _, test := range tests { - test := test t.Run(test.name, func(t *testing.T) { t.Parallel() mechanism, err := SASLMechanismFromString(test.s) @@ -129,7 +128,6 @@ func TestAuthTypeFromString(t *testing.T) { } for _, test := range tests { - test := test t.Run(test.name, func(t *testing.T) { t.Parallel() diff --git a/pkg/sink/cloudstorage/path_test.go b/pkg/sink/cloudstorage/path_test.go index 691c1346b7..0829064807 100644 --- a/pkg/sink/cloudstorage/path_test.go +++ b/pkg/sink/cloudstorage/path_test.go @@ -58,8 +58,7 @@ func testFilePathGenerator(ctx context.Context, t *testing.T, dir string) *FileP func TestGenerateDataFilePath(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.TODO()) - defer cancel() + ctx := t.Context() table := VersionedTableName{ TableNameWithPhysicTableID: model.TableName{ @@ -159,8 +158,7 @@ func TestGenerateDataFilePath(t *testing.T) { func TestFetchIndexFromFileName(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.TODO()) - defer cancel() + ctx := t.Context() dir := t.TempDir() f := testFilePathGenerator(ctx, t, dir) @@ -207,8 +205,7 @@ func TestFetchIndexFromFileName(t *testing.T) { func TestGenerateDataFilePathWithIndexFile(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.TODO()) - defer cancel() + ctx := t.Context() dir := t.TempDir() f := testFilePathGenerator(ctx, t, dir) @@ -291,8 +288,7 @@ func TestIsSchemaFile(t *testing.T) { func TestCheckOrWriteSchema(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() dir := t.TempDir() f := testFilePathGenerator(ctx, t, dir) @@ -355,8 +351,7 @@ func TestCheckOrWriteSchema(t *testing.T) { func TestRemoveExpiredFilesWithoutPartition(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() dir := t.TempDir() uri := fmt.Sprintf("file:///%s?flush-interval=2s", dir) storage, err := util.GetExternalStorageFromURI(ctx, uri) diff --git a/pkg/sink/cloudstorage/table_definition.go b/pkg/sink/cloudstorage/table_definition.go index 8913f1a4f0..841b9a9bd1 100644 --- a/pkg/sink/cloudstorage/table_definition.go +++ b/pkg/sink/cloudstorage/table_definition.go @@ -38,14 +38,14 @@ const ( // TableCol denotes the column info for a table definition. type TableCol struct { - ID string `json:"ColumnId,omitempty"` - Name string `json:"ColumnName" ` - Tp string `json:"ColumnType"` - Default interface{} `json:"ColumnDefault,omitempty"` - Precision string `json:"ColumnPrecision,omitempty"` - Scale string `json:"ColumnScale,omitempty"` - Nullable string `json:"ColumnNullable,omitempty"` - IsPK string `json:"ColumnIsPk,omitempty"` + ID string `json:"ColumnId,omitempty"` + Name string `json:"ColumnName" ` + Tp string `json:"ColumnType"` + Default any `json:"ColumnDefault,omitempty"` + Precision string `json:"ColumnPrecision,omitempty"` + Scale string `json:"ColumnScale,omitempty"` + Nullable string `json:"ColumnNullable,omitempty"` + IsPK string `json:"ColumnIsPk,omitempty"` } // FromTiColumnInfo converts from TiDB ColumnInfo to TableCol. diff --git a/pkg/sink/cloudstorage/table_definition_test.go b/pkg/sink/cloudstorage/table_definition_test.go index d7b774ce5b..90defaf271 100644 --- a/pkg/sink/cloudstorage/table_definition_test.go +++ b/pkg/sink/cloudstorage/table_definition_test.go @@ -515,7 +515,7 @@ func TestTableDefinitionSum32(t *testing.T) { newDef := def newDef.Columns = newCol - for i := 0; i < n; i++ { + for i := range n { target := rand.Intn(n) newDef.Columns[i], newDef.Columns[target] = newDef.Columns[target], newDef.Columns[i] newChecksum, err := newDef.Sum32(nil) diff --git a/pkg/sink/codec/avro/avro.go b/pkg/sink/codec/avro/avro.go index 52cc83da4c..86a344adc7 100644 --- a/pkg/sink/codec/avro/avro.go +++ b/pkg/sink/codec/avro/avro.go @@ -256,7 +256,7 @@ func (a *BatchEncoder) AppendRowChangedEvent( func (a *BatchEncoder) EncodeCheckpointEvent(ts uint64) (*common.Message, error) { if a.config.EnableTiDBExtension && a.config.AvroEnableWatermark { buf := new(bytes.Buffer) - data := []interface{}{checkpointByte, ts} + data := []any{checkpointByte, ts} for _, v := range data { err := binary.Write(buf, binary.BigEndian, v) if err != nil { @@ -327,9 +327,9 @@ func getOperation(e *model.RowChangedEvent) string { } func (a *BatchEncoder) nativeValueWithExtension( - native map[string]interface{}, + native map[string]any, e *model.RowChangedEvent, -) map[string]interface{} { +) map[string]any { native[tidbOp] = getOperation(e) native[tidbCommitTs] = int64(e.CommitTs) native[tidbPhysicalTime] = oracle.ExtractPhysical(e.CommitTs) @@ -343,10 +343,10 @@ func (a *BatchEncoder) nativeValueWithExtension( } type avroSchemaTop struct { - Tp string `json:"type"` - Name string `json:"name"` - Namespace string `json:"namespace"` - Fields []map[string]interface{} `json:"fields"` + Tp string `json:"type"` + Name string `json:"name"` + Namespace string `json:"namespace"` + Fields []map[string]any `json:"fields"` } const ( @@ -474,26 +474,26 @@ type avroSchema struct { type avroLogicalTypeSchema struct { avroSchema - LogicalType string `json:"logicalType"` - Precision interface{} `json:"precision,omitempty"` - Scale interface{} `json:"scale,omitempty"` + LogicalType string `json:"logicalType"` + Precision any `json:"precision,omitempty"` + Scale any `json:"scale,omitempty"` } func (a *BatchEncoder) schemaWithExtension( top *avroSchemaTop, ) *avroSchemaTop { top.Fields = append(top.Fields, - map[string]interface{}{ + map[string]any{ "name": tidbOp, "type": "string", "default": "", }, - map[string]interface{}{ + map[string]any{ "name": tidbCommitTs, "type": "long", "default": 0, }, - map[string]interface{}{ + map[string]any{ "name": tidbPhysicalTime, "type": "long", "default": 0, @@ -502,17 +502,17 @@ func (a *BatchEncoder) schemaWithExtension( if a.config.EnableRowChecksum { top.Fields = append(top.Fields, - map[string]interface{}{ + map[string]any{ "name": tidbRowLevelChecksum, "type": "string", "default": "", }, - map[string]interface{}{ + map[string]any{ "name": tidbCorrupted, "type": "boolean", "default": false, }, - map[string]interface{}{ + map[string]any{ "name": tidbChecksumVersion, "type": "int", "default": 0, @@ -539,7 +539,7 @@ func (a *BatchEncoder) columns2AvroSchema(tableName model.TableName, input avroE if err != nil { return nil, err } - field := make(map[string]interface{}) + field := make(map[string]any) field["name"] = common.SanitizeName(colx.GetName()) copied := colx @@ -553,7 +553,7 @@ func (a *BatchEncoder) columns2AvroSchema(tableName model.TableName, input avroE // https://github.com/linkedin/goavro/issues/202 if _, ok := avroType.(avroLogicalTypeSchema); ok { if colx.GetFlag().IsNullable() { - field["type"] = []interface{}{"null", avroType} + field["type"] = []any{"null", avroType} field["default"] = nil } else { field["type"] = avroType @@ -561,9 +561,9 @@ func (a *BatchEncoder) columns2AvroSchema(tableName model.TableName, input avroE } else { if colx.GetFlag().IsNullable() { if defaultValue == nil { - field["type"] = []interface{}{"null", avroType} + field["type"] = []any{"null", avroType} } else { - field["type"] = []interface{}{avroType, "null"} + field["type"] = []any{avroType, "null"} } field["default"] = defaultValue } else { @@ -617,8 +617,8 @@ func (a *BatchEncoder) key2AvroSchema(tableName model.TableName, keyColumns avro return string(str), nil } -func (a *BatchEncoder) columns2AvroData(input avroEncodeInput) (map[string]interface{}, error) { - ret := make(map[string]interface{}, len(input.columns)) +func (a *BatchEncoder) columns2AvroData(input avroEncodeInput) (map[string]any, error) { + ret := make(map[string]any, len(input.columns)) for _, col := range input.columns { colx := model.GetColumnDataX(col, input.TableInfo) if colx.ColumnData == nil { @@ -642,7 +642,7 @@ func (a *BatchEncoder) columns2AvroData(input avroEncodeInput) (map[string]inter return ret, nil } -func (a *BatchEncoder) columnToAvroSchema(col model.ColumnDataX) (interface{}, error) { +func (a *BatchEncoder) columnToAvroSchema(col model.ColumnDataX) (any, error) { tt := getTiDBTypeFromColumn(col) switch col.GetType() { @@ -779,7 +779,7 @@ func (a *BatchEncoder) columnToAvroSchema(col model.ColumnDataX) (interface{}, e } } -func (a *BatchEncoder) columnToAvroData(col model.ColumnDataX) (interface{}, string, error) { +func (a *BatchEncoder) columnToAvroData(col model.ColumnDataX) (any, string, error) { if col.Value == nil { return nil, "null", nil } @@ -949,7 +949,7 @@ const ( func (r *avroEncodeResult) toEnvelope() ([]byte, error) { buf := new(bytes.Buffer) - data := []interface{}{r.header, r.data} + data := []any{r.header, r.data} for _, v := range data { err := binary.Write(buf, binary.BigEndian, v) if err != nil { diff --git a/pkg/sink/codec/avro/avro_test.go b/pkg/sink/codec/avro/avro_test.go index 54b11ae4cc..591297181e 100644 --- a/pkg/sink/codec/avro/avro_test.go +++ b/pkg/sink/codec/avro/avro_test.go @@ -14,7 +14,6 @@ package avro import ( - "context" "math/rand" "testing" "time" @@ -33,8 +32,7 @@ import ( func TestDMLEventE2E(t *testing.T) { codecConfig := common.NewConfig(config.ProtocolAvro) codecConfig.EnableTiDBExtension = true - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() _, event, _, _ := utils.NewLargeEvent4Test(t, config.GetDefaultReplicaConfig()) colInfos := event.TableInfo.GetColInfosForRowChangedEvent() @@ -151,8 +149,7 @@ func TestAvroEncode4EnableChecksum(t *testing.T) { codecConfig.AvroDecimalHandlingMode = "string" codecConfig.AvroBigintUnsignedHandlingMode = "string" - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() encoder, err := SetupEncoderAndSchemaRegistry4Testing(ctx, codecConfig) defer TeardownEncoderAndSchemaRegistry4Testing() @@ -174,7 +171,7 @@ func TestAvroEncode4EnableChecksum(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) - m, ok := res.(map[string]interface{}) + m, ok := res.(map[string]any) require.True(t, ok) _, found := m[tidbRowLevelChecksum] @@ -191,8 +188,7 @@ func TestAvroEncode(t *testing.T) { codecConfig := common.NewConfig(config.ProtocolAvro) codecConfig.EnableTiDBExtension = true - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() encoder, err := SetupEncoderAndSchemaRegistry4Testing(ctx, codecConfig) defer TeardownEncoderAndSchemaRegistry4Testing() @@ -213,12 +209,12 @@ func TestAvroEncode(t *testing.T) { res, _, err := avroKeyCodec.NativeFromBinary(data) require.NoError(t, err) require.NotNil(t, res) - for k := range res.(map[string]interface{}) { + for k := range res.(map[string]any) { if k == "_tidb_commit_ts" || k == "_tidb_op" || k == "_tidb_commit_physical_time" { require.Fail(t, "key shall not include extension fields") } } - require.Equal(t, int32(127), res.(map[string]interface{})["tu1"]) + require.Equal(t, int32(127), res.(map[string]any)["tu1"]) bin, err = encoder.encodeValue(ctx, topic, event) require.NoError(t, err) @@ -233,7 +229,7 @@ func TestAvroEncode(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) - for k, v := range res.(map[string]interface{}) { + for k, v := range res.(map[string]any) { if k == "_tidb_op" { require.Equal(t, "c", v.(string)) } @@ -258,7 +254,7 @@ func TestAvroEnvelope(t *testing.T) { require.NoError(t, err) - testNativeData := make(map[string]interface{}) + testNativeData := make(map[string]any) testNativeData["id"] = 7 bin, err := avroCodec.BinaryFromNative(nil, testNativeData) @@ -280,7 +276,7 @@ func TestAvroEnvelope(t *testing.T) { require.NoError(t, err) require.NotNil(t, parsed) - id, exists := parsed.(map[string]interface{})["id"] + id, exists := parsed.(map[string]any)["id"] require.True(t, exists) require.Equal(t, int32(7), id) @@ -300,7 +296,7 @@ func TestAvroEnvelope(t *testing.T) { parsed, _, err = avroCodec.NativeFromBinary(evlp[18:]) require.NoError(t, err) require.NotNil(t, parsed) - id, exists = parsed.(map[string]interface{})["id"] + id, exists = parsed.(map[string]any)["id"] require.True(t, exists) require.Equal(t, int32(7), id) } @@ -348,8 +344,7 @@ func TestArvoAppendRowChangedEventWithCallback(t *testing.T) { codecConfig := common.NewConfig(config.ProtocolAvro) codecConfig.EnableTiDBExtension = true - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() encoder, err := SetupEncoderAndSchemaRegistry4Testing(ctx, codecConfig) defer TeardownEncoderAndSchemaRegistry4Testing() require.NoError(t, err) @@ -376,7 +371,7 @@ func TestArvoAppendRowChangedEventWithCallback(t *testing.T) { expected := 0 count := 0 - for i := 0; i < 5; i++ { + for i := range 5 { expected += i bit := i err := encoder.AppendRowChangedEvent(ctx, "", row, func() { diff --git a/pkg/sink/codec/avro/confluent_schema_registry_test.go b/pkg/sink/codec/avro/confluent_schema_registry_test.go index 596323f791..4b358aa9f5 100644 --- a/pkg/sink/codec/avro/confluent_schema_registry_test.go +++ b/pkg/sink/codec/avro/confluent_schema_registry_test.go @@ -125,7 +125,7 @@ func TestSchemaRegistryIdempotent(t *testing.T) { topic := "cdctest" - for i := 0; i < 20; i++ { + for range 20 { err = manager.ClearRegistry(ctx, topic) require.NoError(t, err) } @@ -152,7 +152,7 @@ func TestSchemaRegistryIdempotent(t *testing.T) { require.NoError(t, err) id := 0 - for i := 0; i < 20; i++ { + for range 20 { id1, err := manager.Register(ctx, topic, codec.Schema()) require.NoError(t, err) require.True(t, id == 0 || id == id1.confluentSchemaID) @@ -236,12 +236,10 @@ func TestGetCachedOrRegister(t *testing.T) { } var wg sync.WaitGroup - for i := 0; i < 20; i++ { + for i := range 20 { finalI := i - wg.Add(1) - go func() { - defer wg.Done() - for j := 0; j < 100; j++ { + wg.Go(func() { + for range 100 { codec, header, err := manager.GetCachedOrRegister( ctx, topic, @@ -254,7 +252,7 @@ func TestGetCachedOrRegister(t *testing.T) { require.Greater(t, cID, uint32(0)) require.NotNil(t, codec) } - }() + }) } wg.Wait() } diff --git a/pkg/sink/codec/avro/decoder.go b/pkg/sink/codec/avro/decoder.go index a8474e238f..ea8e2b2c37 100644 --- a/pkg/sink/codec/avro/decoder.go +++ b/pkg/sink/codec/avro/decoder.go @@ -97,8 +97,8 @@ func (d *decoder) HasNext() (model.MessageType, bool, error) { // NextRowChangedEvent returns the next row changed event if exists func (d *decoder) NextRowChangedEvent() (*model.RowChangedEvent, error) { var ( - valueMap map[string]interface{} - valueSchema map[string]interface{} + valueMap map[string]any + valueSchema map[string]any err error ) @@ -175,9 +175,9 @@ func (d *decoder) NextRowChangedEvent() (*model.RowChangedEvent, error) { // valueMap hold all columns information // schema is corresponding to the valueMap, it can be used to decode the valueMap to construct columns. func assembleEvent( - keyMap, valueMap, schema map[string]interface{}, isDelete bool, + keyMap, valueMap, schema map[string]any, isDelete bool, ) (*model.RowChangedEvent, error) { - fields, ok := schema["fields"].([]interface{}) + fields, ok := schema["fields"].([]any) if !ok { return nil, errors.New("schema fields should be a map") } @@ -186,7 +186,7 @@ func assembleEvent( // fields is ordered by the column id, so iterate over it to build columns // it's also the order to calculate the checksum. for _, item := range fields { - field, ok := item.(map[string]interface{}) + field, ok := item.(map[string]any) if !ok { return nil, errors.New("schema field should be a map") } @@ -199,18 +199,18 @@ func assembleEvent( } // query the field to get `tidbType`, and get the mysql type from it. - var holder map[string]interface{} + var holder map[string]any switch ty := field["type"].(type) { - case []interface{}: - if m, ok := ty[0].(map[string]interface{}); ok { - holder = m["connect.parameters"].(map[string]interface{}) - } else if m, ok := ty[1].(map[string]interface{}); ok { - holder = m["connect.parameters"].(map[string]interface{}) + case []any: + if m, ok := ty[0].(map[string]any); ok { + holder = m["connect.parameters"].(map[string]any) + } else if m, ok := ty[1].(map[string]any); ok { + holder = m["connect.parameters"].(map[string]any) } else { log.Panic("type info is anything else", zap.Any("typeInfo", field["type"])) } - case map[string]interface{}: - holder = ty["connect.parameters"].(map[string]interface{}) + case map[string]any: + holder = ty["connect.parameters"].(map[string]any) default: log.Panic("type info is anything else", zap.Any("typeInfo", field["type"])) } @@ -273,7 +273,7 @@ func assembleEvent( return event, nil } -func isCorrupted(valueMap map[string]interface{}) bool { +func isCorrupted(valueMap map[string]any) bool { o, ok := valueMap[tidbCorrupted] if !ok { return false @@ -285,7 +285,7 @@ func isCorrupted(valueMap map[string]interface{}) bool { // extract the checksum from the received value map // return true if the checksum found, and return error if the checksum is not valid -func extractExpectedChecksum(valueMap map[string]interface{}) (uint64, bool, error) { +func extractExpectedChecksum(valueMap map[string]any) (uint64, bool, error) { o, ok := valueMap[tidbRowLevelChecksum] if !ok { return 0, false, nil @@ -304,12 +304,12 @@ func extractExpectedChecksum(valueMap map[string]interface{}) (uint64, bool, err // value is an interface, need to convert it to the real value with the help of type info. // holder has the value's column info. func getColumnValue( - value interface{}, holder map[string]interface{}, mysqlType byte, -) (interface{}, error) { + value any, holder map[string]any, mysqlType byte, +) (any, error) { switch t := value.(type) { // for nullable columns, the value is encoded as a map with one pair. // key is the encoded type, value is the encoded value, only care about the value here. - case map[string]interface{}: + case map[string]any: for _, v := range t { value = v } @@ -422,7 +422,7 @@ func extractGlueSchemaIDAndBinaryData(data []byte) (string, []byte, error) { func decodeRawBytes( ctx context.Context, schemaM SchemaManager, data []byte, topic string, -) (map[string]interface{}, map[string]interface{}, error) { +) (map[string]any, map[string]any, error) { var schemaID schemaID var binary []byte var err error @@ -456,12 +456,12 @@ func decodeRawBytes( return nil, nil, err } - result, ok := native.(map[string]interface{}) + result, ok := native.(map[string]any) if !ok { return nil, nil, errors.New("raw avro message is not a map") } - schema := make(map[string]interface{}) + schema := make(map[string]any) if err := json.Unmarshal([]byte(codec.Schema()), &schema); err != nil { return nil, nil, errors.Trace(err) } @@ -469,13 +469,13 @@ func decodeRawBytes( return result, schema, nil } -func (d *decoder) decodeKey(ctx context.Context) (map[string]interface{}, map[string]interface{}, error) { +func (d *decoder) decodeKey(ctx context.Context) (map[string]any, map[string]any, error) { data := d.key d.key = nil return decodeRawBytes(ctx, d.schemaM, data, d.topic) } -func (d *decoder) decodeValue(ctx context.Context) (map[string]interface{}, map[string]interface{}, error) { +func (d *decoder) decodeValue(ctx context.Context) (map[string]any, map[string]any, error) { data := d.value d.value = nil return decodeRawBytes(ctx, d.schemaM, data, d.topic) diff --git a/pkg/sink/codec/bootstraper.go b/pkg/sink/codec/bootstraper.go index 32f52e3944..ffe49f6608 100644 --- a/pkg/sink/codec/bootstraper.go +++ b/pkg/sink/codec/bootstraper.go @@ -88,7 +88,7 @@ func (b *bootstrapWorker) run(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() case <-sendTicker.C: - b.activeTables.Range(func(key, value interface{}) bool { + b.activeTables.Range(func(key, value any) bool { table := value.(*tableStatistic) err = b.sendBootstrapMsg(ctx, table) return err == nil @@ -180,7 +180,7 @@ func (b *bootstrapWorker) generateEvents( } func (b *bootstrapWorker) gcInactiveTables() { - b.activeTables.Range(func(key, value interface{}) bool { + b.activeTables.Range(func(key, value any) bool { table := value.(*tableStatistic) if table.isInactive(b.maxInactiveDuration) { log.Info("A table is removed from the bootstrap worker", diff --git a/pkg/sink/codec/bootstraper_test.go b/pkg/sink/codec/bootstraper_test.go index ae11bdc1e1..8555fa13e8 100644 --- a/pkg/sink/codec/bootstraper_test.go +++ b/pkg/sink/codec/bootstraper_test.go @@ -114,8 +114,7 @@ func TestBootstrapWorker(t *testing.T) { defaultMaxInactiveDuration) // Start the worker in a separate goroutine - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() go func() { _ = worker.run(ctx) }() diff --git a/pkg/sink/codec/canal/canal_entry.go b/pkg/sink/codec/canal/canal_entry.go index 8925ed8812..1252bcaed3 100644 --- a/pkg/sink/codec/canal/canal_entry.go +++ b/pkg/sink/codec/canal/canal_entry.go @@ -81,7 +81,7 @@ func (b *canalEntryBuilder) buildHeader(commitTs uint64, schema string, table st // see https://github.com/alibaba/canal/blob/b54bea5e3337c9597c427a53071d214ff04628d1/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/RowsLogBuffer.java#L276-L1147 // all value will be represented in string type // see https://github.com/alibaba/canal/blob/b54bea5e3337c9597c427a53071d214ff04628d1/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/LogEventConvert.java#L760-L855 -func (b *canalEntryBuilder) formatValue(value interface{}, isBinary bool) (result string, err error) { +func (b *canalEntryBuilder) formatValue(value any, isBinary bool) (result string, err error) { // value would be nil, if no value insert for the column. if value == nil { return "", nil @@ -301,7 +301,7 @@ func isCanalDDL(t canal.EventType) bool { return false } -func getJavaSQLType(value interface{}, tp byte, flag model.ColumnFlagType) (result internal.JavaSQLType, err error) { +func getJavaSQLType(value any, tp byte, flag model.ColumnFlagType) (result internal.JavaSQLType, err error) { javaType := internal.MySQLType2JavaType(tp, flag.IsBinary()) // flag `isUnsigned` only for `numerical` and `bit`, `year` data type. if !flag.IsUnsigned() { diff --git a/pkg/sink/codec/canal/canal_json_decoder.go b/pkg/sink/codec/canal/canal_json_decoder.go index 5e3114c054..30a1a37242 100644 --- a/pkg/sink/codec/canal/canal_json_decoder.go +++ b/pkg/sink/codec/canal/canal_json_decoder.go @@ -69,7 +69,7 @@ func (b *bufferedJSONDecoder) Write(data []byte) (n int, err error) { } // Decode decodes the buffer into the original message. -func (b *bufferedJSONDecoder) Decode(v interface{}) error { +func (b *bufferedJSONDecoder) Decode(v any) error { return b.decoder.Decode(v) } @@ -202,12 +202,12 @@ func (b *batchDecoder) assembleClaimCheckRowChangedEvent(ctx context.Context, cl return b.NextRowChangedEvent() } -func (b *batchDecoder) buildData(holder *common.ColumnsHolder) (map[string]interface{}, map[string]string, error) { +func (b *batchDecoder) buildData(holder *common.ColumnsHolder) (map[string]any, map[string]string, error) { columnsCount := holder.Length() - data := make(map[string]interface{}, columnsCount) + data := make(map[string]any, columnsCount) mysqlTypeMap := make(map[string]string, columnsCount) - for i := 0; i < columnsCount; i++ { + for i := range columnsCount { t := holder.Types[i] name := holder.Types[i].Name() mysqlType := strings.ToLower(t.DatabaseTypeName()) @@ -242,7 +242,7 @@ func (b *batchDecoder) assembleHandleKeyOnlyRowChangedEvent( table = message.Table eventType = message.EventType ) - conditions := make(map[string]interface{}, len(message.pkNameSet())) + conditions := make(map[string]any, len(message.pkNameSet())) for name := range message.pkNameSet() { conditions[name] = message.getData()[name] } @@ -266,7 +266,7 @@ func (b *batchDecoder) assembleHandleKeyOnlyRowChangedEvent( return nil, err } result.MySQLType = mysqlType - result.Data = []map[string]interface{}{data} + result.Data = []map[string]any{data} case "UPDATE": holder := common.MustSnapshotQuery(ctx, b.upstreamTiDB, commitTs, schema, table, conditions) data, mysqlType, err := b.buildData(holder) @@ -274,14 +274,14 @@ func (b *batchDecoder) assembleHandleKeyOnlyRowChangedEvent( return nil, err } result.MySQLType = mysqlType - result.Data = []map[string]interface{}{data} + result.Data = []map[string]any{data} holder = common.MustSnapshotQuery(ctx, b.upstreamTiDB, commitTs-1, schema, table, conditions) old, _, err := b.buildData(holder) if err != nil { return nil, err } - result.Old = []map[string]interface{}{old} + result.Old = []map[string]any{old} case "DELETE": holder := common.MustSnapshotQuery(ctx, b.upstreamTiDB, commitTs-1, schema, table, conditions) data, mysqlType, err := b.buildData(holder) @@ -289,7 +289,7 @@ func (b *batchDecoder) assembleHandleKeyOnlyRowChangedEvent( return nil, err } result.MySQLType = mysqlType - result.Data = []map[string]interface{}{data} + result.Data = []map[string]any{data} } b.msg = result @@ -298,7 +298,7 @@ func (b *batchDecoder) assembleHandleKeyOnlyRowChangedEvent( func setColumnInfos( tableInfo *timodel.TableInfo, - rawColumns map[string]interface{}, + rawColumns map[string]any, mysqlType map[string]string, pkNames map[string]struct{}, ) { diff --git a/pkg/sink/codec/canal/canal_json_message.go b/pkg/sink/codec/canal/canal_json_message.go index e4610f061c..7024e1335c 100644 --- a/pkg/sink/codec/canal/canal_json_message.go +++ b/pkg/sink/codec/canal/canal_json_message.go @@ -41,8 +41,8 @@ type canalJSONMessageInterface interface { getPhysicalTableID() int64 getTableID() int64 getQuery() string - getOld() map[string]interface{} - getData() map[string]interface{} + getOld() map[string]any + getData() map[string]any getMySQLType() map[string]string getJavaSQLType() map[string]int32 messageType() model.MessageType @@ -70,8 +70,8 @@ type JSONMessage struct { // only works for INSERT / UPDATE / DELETE events, records each column's mysql representation type. MySQLType map[string]string `json:"mysqlType"` // A Datum should be a string or nil - Data []map[string]interface{} `json:"data"` - Old []map[string]interface{} `json:"old"` + Data []map[string]any `json:"data"` + Old []map[string]any `json:"old"` } func (c *JSONMessage) getSchema() *string { @@ -99,14 +99,14 @@ func (c *JSONMessage) getQuery() string { return c.Query } -func (c *JSONMessage) getOld() map[string]interface{} { +func (c *JSONMessage) getOld() map[string]any { if c.Old == nil { return nil } return c.Old[0] } -func (c *JSONMessage) getData() map[string]interface{} { +func (c *JSONMessage) getData() map[string]any { if c.Data == nil { return nil } @@ -328,7 +328,7 @@ func (b *batchDecoder) canalJSONMessage2RowChange() (*model.RowChangedEvent, err } func canalJSONColumnMap2RowChangeColumns( - cols map[string]interface{}, + cols map[string]any, mysqlType map[string]string, tableInfo *model.TableInfo, ) ([]*model.ColumnData, error) { @@ -352,7 +352,7 @@ func canalJSONColumnMap2RowChangeColumns( return result, nil } -func canalJSONFormatColumn(columnID int64, value interface{}, mysqlTypeStr string) *model.ColumnData { +func canalJSONFormatColumn(columnID int64, value any, mysqlTypeStr string) *model.ColumnData { mysqlType := utils.ExtractBasicMySQLType(mysqlTypeStr) result := &model.ColumnData{ ColumnID: columnID, diff --git a/pkg/sink/codec/common/helper.go b/pkg/sink/codec/common/helper.go index b42599a7c4..f2737ecf66 100644 --- a/pkg/sink/codec/common/helper.go +++ b/pkg/sink/codec/common/helper.go @@ -31,8 +31,8 @@ import ( // ColumnsHolder read columns from sql.Rows type ColumnsHolder struct { - Values []interface{} - ValuePointers []interface{} + Values []any + ValuePointers []any Types []*sql.ColumnType } @@ -42,8 +42,8 @@ func newColumnHolder(rows *sql.Rows) (*ColumnsHolder, error) { return nil, errors.Trace(err) } - values := make([]interface{}, len(columnTypes)) - valuePointers := make([]interface{}, len(columnTypes)) + values := make([]any, len(columnTypes)) + valuePointers := make([]any, len(columnTypes)) for i := range values { valuePointers[i] = &values[i] } @@ -105,7 +105,7 @@ func queryRowChecksum( defer conn.Close() if event.Checksum.Current != 0 { - conditions := make(map[string]interface{}) + conditions := make(map[string]any) for _, name := range pkNames { for _, col := range event.Columns { if event.TableInfo.ForceGetColumnName(col.ColumnID) == name { @@ -123,7 +123,7 @@ func queryRowChecksum( } if event.Checksum.Previous != 0 { - conditions := make(map[string]interface{}) + conditions := make(map[string]any) for _, name := range pkNames { for _, col := range event.PreColumns { if event.TableInfo.ForceGetColumnName(col.ColumnID) == name { @@ -144,7 +144,7 @@ func queryRowChecksum( } func queryRowChecksumAux( - ctx context.Context, conn *sql.Conn, commitTs uint64, schema string, table string, conditions map[string]interface{}, + ctx context.Context, conn *sql.Conn, commitTs uint64, schema string, table string, conditions map[string]any, ) uint32 { var result uint32 // 1. set snapshot read @@ -193,7 +193,7 @@ func queryRowChecksumAux( // MustSnapshotQuery query the db by the snapshot read with the given commitTs func MustSnapshotQuery( - ctx context.Context, db *sql.DB, commitTs uint64, schema, table string, conditions map[string]interface{}, + ctx context.Context, db *sql.DB, commitTs uint64, schema, table string, conditions map[string]any, ) *ColumnsHolder { conn, err := db.Conn(ctx) if err != nil { diff --git a/pkg/sink/codec/common/verify_checksum.go b/pkg/sink/codec/common/verify_checksum.go index 589ae8680d..723b9edd5f 100644 --- a/pkg/sink/codec/common/verify_checksum.go +++ b/pkg/sink/codec/common/verify_checksum.go @@ -104,7 +104,7 @@ func calculateChecksum(columns []*model.ColumnData, columnInfo []*timodel.Column // buildChecksumBytes append value to the buf, mysqlType is used to convert value interface to concrete type. // by follow: https://github.com/pingcap/tidb/blob/e3417913f58cdd5a136259b902bf177eaf3aa637/util/rowcodec/common.go#L308 -func buildChecksumBytes(buf []byte, value interface{}, mysqlType byte) ([]byte, error) { +func buildChecksumBytes(buf []byte, value any, mysqlType byte) ([]byte, error) { if value == nil { return buf, nil } @@ -133,7 +133,7 @@ func buildChecksumBytes(buf []byte, value interface{}, mysqlType byte) ([]byte, if err != nil { return nil, errors.Trace(err) } - case map[string]interface{}: + case map[string]any: // this may only happen for bigint larger than math.uint64 v = uint64(a["value"].(int64)) default: @@ -191,7 +191,7 @@ func buildChecksumBytes(buf []byte, value interface{}, mysqlType byte) ([]byte, location := "Local" var ts string switch data := value.(type) { - case map[string]interface{}: + case map[string]any: ts = data["value"].(string) location = data["location"].(string) case string: diff --git a/pkg/sink/codec/craft/craft_encoder_test.go b/pkg/sink/codec/craft/craft_encoder_test.go index c676429b48..c4cff962a1 100644 --- a/pkg/sink/codec/craft/craft_encoder_test.go +++ b/pkg/sink/codec/craft/craft_encoder_test.go @@ -35,7 +35,7 @@ func TestCraftMaxMessageBytes(t *testing.T) { _ = helper.DDL2Event(`create table test.t(a varchar(10) primary key)`) testEvent := helper.DML2Event(`insert into test.t values ("aa")`, "test", "t") - for i := 0; i < 10000; i++ { + for range 10000 { err := encoder.AppendRowChangedEvent(context.Background(), "", testEvent, nil) require.Nil(t, err) } @@ -57,7 +57,7 @@ func TestCraftMaxBatchSize(t *testing.T) { _ = helper.DDL2Event(`create table test.t(a varchar(10) primary key)`) testEvent := helper.DML2Event(`insert into test.t values ("aa")`, "test", "t") - for i := 0; i < 10000; i++ { + for range 10000 { err := encoder.AppendRowChangedEvent(context.Background(), "", testEvent, nil) require.Nil(t, err) } diff --git a/pkg/sink/codec/craft/message_decoder.go b/pkg/sink/codec/craft/message_decoder.go index c104277e82..e90506b536 100644 --- a/pkg/sink/codec/craft/message_decoder.go +++ b/pkg/sink/codec/craft/message_decoder.go @@ -146,7 +146,7 @@ func decodeStringChunk(bits []byte, size int, allocator *SliceAllocator) ([]byte newBits := bits var bl int var err error - for i := 0; i < size; i++ { + for i := range size { newBits, bl, err = decodeUvarintLength(newBits) if err != nil { return bits, nil, errors.Trace(err) @@ -155,7 +155,7 @@ func decodeStringChunk(bits []byte, size int, allocator *SliceAllocator) ([]byte } data := allocator.stringSlice(size) - for i := 0; i < size; i++ { + for i := range size { data[i] = common.UnsafeBytesToString(newBits[:larray[i]]) newBits = newBits[larray[i]:] } @@ -167,7 +167,7 @@ func decodeNullableStringChunk(bits []byte, size int, allocator *SliceAllocator) newBits := bits var bl int var err error - for i := 0; i < size; i++ { + for i := range size { newBits, bl, err = decodeVarintLength(newBits) if err != nil { return bits, nil, errors.Trace(err) @@ -176,7 +176,7 @@ func decodeNullableStringChunk(bits []byte, size int, allocator *SliceAllocator) } data := allocator.nullableStringSlice(size) - for i := 0; i < size; i++ { + for i := range size { if larray[i] == -1 { continue } @@ -197,7 +197,7 @@ func doDecodeBytesChunk(bits []byte, size int, lengthDecoder func([]byte) ([]byt newBits := bits var bl int var err error - for i := 0; i < size; i++ { + for i := range size { newBits, bl, err = lengthDecoder(newBits) if err != nil { return bits, nil, errors.Trace(err) @@ -206,7 +206,7 @@ func doDecodeBytesChunk(bits []byte, size int, lengthDecoder func([]byte) ([]byt } data := allocator.bytesSlice(size) - for i := 0; i < size; i++ { + for i := range size { if larray[i] != -1 { data[i] = newBits[:larray[i]] newBits = newBits[larray[i]:] @@ -224,7 +224,7 @@ func decodeVarintChunk(bits []byte, size int, allocator *SliceAllocator) ([]byte newBits := bits var i64 int64 var err error - for i := 0; i < size; i++ { + for i := range size { newBits, i64, err = decodeVarint(newBits) if err != nil { return bits, nil, errors.Trace(err) @@ -239,7 +239,7 @@ func decodeUvarintChunk(bits []byte, size int, allocator *SliceAllocator) ([]byt newBits := bits var u64 uint64 var err error - for i := 0; i < size; i++ { + for i := range size { newBits, u64, err = decodeUvarint(newBits) if err != nil { return bits, nil, errors.Trace(err) @@ -312,7 +312,7 @@ func decodeSizeTables(bits []byte, allocator *SliceAllocator) (int, [][]int64, e } // DecodeTiDBType decodes TiDB types. -func DecodeTiDBType(ty byte, flag model.ColumnFlagType, bits []byte) (interface{}, error) { +func DecodeTiDBType(ty byte, flag model.ColumnFlagType, bits []byte) (any, error) { if bits == nil { return nil, nil } diff --git a/pkg/sink/codec/craft/message_encoder.go b/pkg/sink/codec/craft/message_encoder.go index f09c9e6016..11138f842f 100644 --- a/pkg/sink/codec/craft/message_encoder.go +++ b/pkg/sink/codec/craft/message_encoder.go @@ -176,7 +176,7 @@ func encodeSizeTables(bits []byte, tables [][]int64) []byte { } // EncodeTiDBType encodes TiDB types -func EncodeTiDBType(allocator *SliceAllocator, ty byte, flag model.ColumnFlagType, value interface{}) []byte { +func EncodeTiDBType(allocator *SliceAllocator, ty byte, flag model.ColumnFlagType, value any) []byte { if value == nil { return nil } diff --git a/pkg/sink/codec/csv/csv_decoder_test.go b/pkg/sink/codec/csv/csv_decoder_test.go index 81e77ae5e6..d9b6d6bc70 100644 --- a/pkg/sink/codec/csv/csv_decoder_test.go +++ b/pkg/sink/codec/csv/csv_decoder_test.go @@ -46,7 +46,7 @@ func TestCSVBatchDecoder(t *testing.T) { decoder, err := NewBatchDecoder(ctx, codecConfig, createTableDDL.TableInfo, []byte(csvData)) require.NoError(t, err) - for i := 0; i < 5; i++ { + for range 5 { tp, hasNext, err := decoder.HasNext() require.Nil(t, err) require.True(t, hasNext) diff --git a/pkg/sink/codec/csv/csv_message_test.go b/pkg/sink/codec/csv/csv_message_test.go index 4718cd6e39..4fd592f92d 100644 --- a/pkg/sink/codec/csv/csv_message_test.go +++ b/pkg/sink/codec/csv/csv_message_test.go @@ -32,7 +32,7 @@ import ( type csvTestColumnTuple struct { col model.Column colInfo rowcodec.ColInfo - want interface{} + want any BinaryEncodingMethod string } diff --git a/pkg/sink/codec/debezium/codec.go b/pkg/sink/codec/debezium/codec.go index deaf4eed65..bc139b2d3a 100644 --- a/pkg/sink/codec/debezium/codec.go +++ b/pkg/sink/codec/debezium/codec.go @@ -42,7 +42,7 @@ type dbzCodec struct { // truncateValueForLog truncates large values to avoid log flooding. // Returns the original value if it's small enough, otherwise returns a truncated string representation. -func truncateValueForLog(value interface{}, maxLen int) interface{} { +func truncateValueForLog(value any, maxLen int) any { switch v := value.(type) { case []byte: if len(v) > maxLen { diff --git a/pkg/sink/codec/debezium/debezium_test.go b/pkg/sink/codec/debezium/debezium_test.go index aa39bfe211..a5fbee750d 100644 --- a/pkg/sink/codec/debezium/debezium_test.go +++ b/pkg/sink/codec/debezium/debezium_test.go @@ -87,7 +87,7 @@ func (h *SQLTestHelper) Close() { h.helper.Close() } -func (h *SQLTestHelper) MustExec(query string, args ...interface{}) { +func (h *SQLTestHelper) MustExec(query string, args ...any) { h.helper.Tk().MustExec(query, args...) } diff --git a/pkg/sink/codec/debezium/decoder.go b/pkg/sink/codec/debezium/decoder.go index 462a12cf3a..d5152aff82 100644 --- a/pkg/sink/codec/debezium/decoder.go +++ b/pkg/sink/codec/debezium/decoder.go @@ -45,10 +45,10 @@ type Decoder struct { upstreamTiDB *sql.DB tableIDAllocator *common.FakeTableIDAllocator - keyPayload map[string]interface{} - keySchema map[string]interface{} - valuePayload map[string]interface{} - valueSchema map[string]interface{} + keyPayload map[string]any + keySchema map[string]any + valuePayload map[string]any + valueSchema map[string]any } // NewDecoder return an debezium decoder @@ -153,10 +153,10 @@ func (d *Decoder) NextRowChangedEvent() (*model.RowChangedEvent, error) { CommitTs: commitTs, TableInfo: tableInfo, } - if before, ok := d.valuePayload["before"].(map[string]interface{}); ok { + if before, ok := d.valuePayload["before"].(map[string]any); ok { event.PreColumns = assembleColumnData(before, tableInfo) } - if after, ok := d.valuePayload["after"].(map[string]interface{}); ok { + if after, ok := d.valuePayload["after"].(map[string]any); ok { event.Columns = assembleColumnData(after, tableInfo) } event.PhysicalTableID = d.tableIDAllocator.AllocateTableID(tableInfo.GetSchemaName(), tableInfo.GetTableName()) @@ -164,7 +164,7 @@ func (d *Decoder) NextRowChangedEvent() (*model.RowChangedEvent, error) { } func (d *Decoder) getCommitTs() uint64 { - source := d.valuePayload["source"].(map[string]interface{}) + source := d.valuePayload["source"].(map[string]any) commitTs, err := source["commit_ts"].(json.Number).Int64() if err != nil { log.Error("decode value failed", zap.Error(err), zap.Any("value", source)) @@ -173,13 +173,13 @@ func (d *Decoder) getCommitTs() uint64 { } func (d *Decoder) getSchemaName() string { - source := d.valuePayload["source"].(map[string]interface{}) + source := d.valuePayload["source"].(map[string]any) schemaName := source["db"].(string) return schemaName } func (d *Decoder) getTableName() string { - source := d.valuePayload["source"].(map[string]interface{}) + source := d.valuePayload["source"].(map[string]any) tableName := source["table"].(string) return tableName } @@ -195,12 +195,12 @@ func (d *Decoder) getTableInfo() *model.TableInfo { tidbTableInfo := new(timodel.TableInfo) tidbTableInfo.Name = pmodel.NewCIStr(d.getTableName()) columnIDAllocator := model.NewIncrementalColumnIDAllocator() - fields := d.valueSchema["fields"].([]interface{}) - after := fields[1].(map[string]interface{}) - columnsField := after["fields"].([]interface{}) + fields := d.valueSchema["fields"].([]any) + after := fields[1].(map[string]any) + columnsField := after["fields"].([]any) indexColumns := make([]*timodel.IndexColumn, 0, len(d.keyPayload)) for idx, column := range columnsField { - col := column.(map[string]interface{}) + col := column.(map[string]any) colName := col["field"].(string) tidbType := col["tidb_type"].(string) optional := col["optional"].(bool) @@ -235,7 +235,7 @@ func (d *Decoder) getTableInfo() *model.TableInfo { return model.WrapTableInfo(100, d.getSchemaName(), 100, tidbTableInfo) } -func assembleColumnData(data map[string]interface{}, tableInfo *model.TableInfo) []*model.ColumnData { +func assembleColumnData(data map[string]any, tableInfo *model.TableInfo) []*model.ColumnData { result := make([]*model.ColumnData, 0, len(data)) for key, value := range data { columnID := tableInfo.ForceGetColumnIDByName(key) @@ -248,7 +248,7 @@ func assembleColumnData(data map[string]interface{}, tableInfo *model.TableInfo) return result } -func decodeColumn(value interface{}, colInfo *timodel.ColumnInfo) *model.ColumnData { +func decodeColumn(value any, colInfo *timodel.ColumnInfo) *model.ColumnData { result := &model.ColumnData{ ColumnID: colInfo.ID, Value: value, @@ -357,18 +357,18 @@ func parseTiDBType(tidbType string, optional bool) *ptypes.FieldType { return ft } -func decodeRawBytes(data []byte) (map[string]interface{}, map[string]interface{}, error) { - var v map[string]interface{} +func decodeRawBytes(data []byte) (map[string]any, map[string]any, error) { + var v map[string]any d := json.NewDecoder(bytes.NewBuffer(data)) d.UseNumber() if err := d.Decode(&v); err != nil { return nil, nil, errors.Trace(err) } - payload, ok := v["payload"].(map[string]interface{}) + payload, ok := v["payload"].(map[string]any) if !ok { return nil, nil, fmt.Errorf("decode payload failed, data: %+v", v) } - schema, ok := v["schema"].(map[string]interface{}) + schema, ok := v["schema"].(map[string]any) if !ok { return nil, nil, fmt.Errorf("decode payload failed, data: %+v", v) } diff --git a/pkg/sink/codec/encoder.go b/pkg/sink/codec/encoder.go index e3b232c9f0..421f281238 100644 --- a/pkg/sink/codec/encoder.go +++ b/pkg/sink/codec/encoder.go @@ -73,7 +73,7 @@ type TxnEventEncoderBuilder interface { } // IsColumnValueEqual checks whether the preValue and updatedValue are equal. -func IsColumnValueEqual(preValue, updatedValue interface{}) bool { +func IsColumnValueEqual(preValue, updatedValue any) bool { if preValue == nil || updatedValue == nil { return preValue == updatedValue } diff --git a/pkg/sink/codec/maxwell/maxwell_message.go b/pkg/sink/codec/maxwell/maxwell_message.go index f673ad5b4f..8d13d1ba96 100644 --- a/pkg/sink/codec/maxwell/maxwell_message.go +++ b/pkg/sink/codec/maxwell/maxwell_message.go @@ -26,16 +26,16 @@ import ( ) type maxwellMessage struct { - Database string `json:"database"` - Table string `json:"table"` - Type string `json:"type"` - Ts int64 `json:"ts"` - Xid int `json:"xid,omitempty"` - Xoffset int `json:"xoffset,omitempty"` - Position string `json:"position,omitempty"` - Gtid string `json:"gtid,omitempty"` - Data map[string]interface{} `json:"data,omitempty"` - Old map[string]interface{} `json:"old,omitempty"` + Database string `json:"database"` + Table string `json:"table"` + Type string `json:"type"` + Ts int64 `json:"ts"` + Xid int `json:"xid,omitempty"` + Xoffset int `json:"xoffset,omitempty"` + Position string `json:"position,omitempty"` + Gtid string `json:"gtid,omitempty"` + Data map[string]any `json:"data,omitempty"` + Old map[string]any `json:"old,omitempty"` } // Encode encodes the message to bytes @@ -61,8 +61,8 @@ func rowChangeToMaxwellMsg(e *model.RowChangedEvent, onlyHandleKeyColumns bool) Ts: 0, Database: e.TableInfo.GetSchemaName(), Table: e.TableInfo.GetTableName(), - Data: make(map[string]interface{}), - Old: make(map[string]interface{}), + Data: make(map[string]any), + Old: make(map[string]any), } physicalTime := oracle.GetTimeFromTS(e.CommitTs) value.Ts = physicalTime.Unix() @@ -178,8 +178,8 @@ type ddlMaxwellMessage struct { Type string `json:"type"` Database string `json:"database"` Table string `json:"table"` - Old tableStruct `json:"old,omitempty"` - Def tableStruct `json:"def,omitempty"` + Old tableStruct `json:"old"` + Def tableStruct `json:"def"` Ts uint64 `json:"ts"` SQL string `json:"sql"` Position string `json:"position,omitempty"` diff --git a/pkg/sink/codec/maxwell/maxwell_message_test.go b/pkg/sink/codec/maxwell/maxwell_message_test.go index f2631c36f0..3cdb784077 100644 --- a/pkg/sink/codec/maxwell/maxwell_message_test.go +++ b/pkg/sink/codec/maxwell/maxwell_message_test.go @@ -31,7 +31,7 @@ func TestMaxwellFormatCol(t *testing.T) { Xoffset: 1, Position: "", Gtid: "", - Data: map[string]interface{}{ + Data: map[string]any{ "id": "1", }, } diff --git a/pkg/sink/codec/open/open_protocol_decoder.go b/pkg/sink/codec/open/open_protocol_decoder.go index db449f29ad..9ec3ddd739 100644 --- a/pkg/sink/codec/open/open_protocol_decoder.go +++ b/pkg/sink/codec/open/open_protocol_decoder.go @@ -218,16 +218,16 @@ func (b *BatchDecoder) NextRowChangedEvent() (*model.RowChangedEvent, error) { } func (b *BatchDecoder) buildColumns( - holder *common.ColumnsHolder, handleKeyColumns map[string]interface{}, + holder *common.ColumnsHolder, handleKeyColumns map[string]any, ) []*model.Column { columnsCount := holder.Length() columns := make([]*model.Column, 0, columnsCount) - for i := 0; i < columnsCount; i++ { + for i := range columnsCount { columnType := holder.Types[i] name := columnType.Name() mysqlType := types.StrToType(strings.ToLower(columnType.DatabaseTypeName())) - var value interface{} + var value any value = holder.Values[i].([]uint8) switch mysqlType { @@ -262,7 +262,7 @@ func (b *BatchDecoder) assembleHandleKeyOnlyEvent( tableInfo := handleKeyOnlyEvent.TableInfo if handleKeyOnlyEvent.IsInsert() { - conditions := make(map[string]interface{}, len(handleKeyOnlyEvent.Columns)) + conditions := make(map[string]any, len(handleKeyOnlyEvent.Columns)) for _, col := range handleKeyOnlyEvent.Columns { colName := tableInfo.ForceGetColumnName(col.ColumnID) conditions[colName] = col.Value @@ -273,7 +273,7 @@ func (b *BatchDecoder) assembleHandleKeyOnlyEvent( handleKeyOnlyEvent.TableInfo = model.BuildTableInfo(schema, table, columns, indexColumns) handleKeyOnlyEvent.Columns = model.Columns2ColumnDatas(columns, handleKeyOnlyEvent.TableInfo) } else if handleKeyOnlyEvent.IsDelete() { - conditions := make(map[string]interface{}, len(handleKeyOnlyEvent.PreColumns)) + conditions := make(map[string]any, len(handleKeyOnlyEvent.PreColumns)) for _, col := range handleKeyOnlyEvent.PreColumns { colName := tableInfo.ForceGetColumnName(col.ColumnID) conditions[colName] = col.Value @@ -284,7 +284,7 @@ func (b *BatchDecoder) assembleHandleKeyOnlyEvent( handleKeyOnlyEvent.TableInfo = model.BuildTableInfo(schema, table, preColumns, indexColumns) handleKeyOnlyEvent.PreColumns = model.Columns2ColumnDatas(preColumns, handleKeyOnlyEvent.TableInfo) } else if handleKeyOnlyEvent.IsUpdate() { - conditions := make(map[string]interface{}, len(handleKeyOnlyEvent.Columns)) + conditions := make(map[string]any, len(handleKeyOnlyEvent.Columns)) for _, col := range handleKeyOnlyEvent.Columns { colName := tableInfo.ForceGetColumnName(col.ColumnID) conditions[colName] = col.Value @@ -295,7 +295,7 @@ func (b *BatchDecoder) assembleHandleKeyOnlyEvent( handleKeyOnlyEvent.TableInfo = model.BuildTableInfo(schema, table, columns, indexColumns) handleKeyOnlyEvent.Columns = model.Columns2ColumnDatas(columns, handleKeyOnlyEvent.TableInfo) - conditions = make(map[string]interface{}, len(handleKeyOnlyEvent.PreColumns)) + conditions = make(map[string]any, len(handleKeyOnlyEvent.PreColumns)) for _, col := range handleKeyOnlyEvent.PreColumns { colName := tableInfo.ForceGetColumnName(col.ColumnID) conditions[colName] = col.Value diff --git a/pkg/sink/codec/open/open_protocol_encoder_test.go b/pkg/sink/codec/open/open_protocol_encoder_test.go index e781819134..0a391cf19b 100644 --- a/pkg/sink/codec/open/open_protocol_encoder_test.go +++ b/pkg/sink/codec/open/open_protocol_encoder_test.go @@ -71,7 +71,7 @@ func TestMaxMessageBytes(t *testing.T) { builder, err = NewBatchEncoderBuilder(ctx, codecConfig) require.NoError(t, err) encoder = builder.Build() - for i := 0; i < 10000; i++ { + for range 10000 { err := encoder.AppendRowChangedEvent(ctx, topic, event, nil) require.NoError(t, err) } @@ -96,7 +96,7 @@ func TestMaxBatchSize(t *testing.T) { require.NoError(t, err) encoder := builder.Build() - for i := 0; i < 10000; i++ { + for range 10000 { err := encoder.AppendRowChangedEvent(ctx, "", event, nil) require.NoError(t, err) } diff --git a/pkg/sink/codec/simple/avro.go b/pkg/sink/codec/simple/avro.go index 8fd93b61a6..79111c49d3 100644 --- a/pkg/sink/codec/simple/avro.go +++ b/pkg/sink/codec/simple/avro.go @@ -23,11 +23,11 @@ import ( "github.com/pingcap/tiflow/cdc/model" ) -func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { +func newTableSchemaMap(tableInfo *model.TableInfo) any { pkInIndexes := false - indexesSchema := make([]interface{}, 0, len(tableInfo.Indices)) + indexesSchema := make([]any, 0, len(tableInfo.Indices)) for _, idx := range tableInfo.Indices { - index := map[string]interface{}{ + index := map[string]any{ "name": idx.Name.O, "unique": idx.Unique, "primary": idx.Primary, @@ -53,7 +53,7 @@ func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { if !pkInIndexes { pkColumns := tableInfo.GetPrimaryKeyColumnNames() if len(pkColumns) != 0 { - index := map[string]interface{}{ + index := map[string]any{ "name": "primary", "nullable": false, "primary": true, @@ -68,9 +68,9 @@ func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { return tableInfo.Columns[i].ID < tableInfo.Columns[j].ID }) - columnsSchema := make([]interface{}, 0, len(tableInfo.Columns)) + columnsSchema := make([]any, 0, len(tableInfo.Columns)) for _, col := range tableInfo.Columns { - mysqlType := map[string]interface{}{ + mysqlType := map[string]any{ "mysqlType": types.TypeToStr(col.GetType(), col.GetCharset()), "charset": col.GetCharset(), "collate": col.GetCollate(), @@ -80,30 +80,30 @@ func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { switch col.GetType() { case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeFloat, mysql.TypeDouble, mysql.TypeBit, mysql.TypeYear: - mysqlType["unsigned"] = map[string]interface{}{ + mysqlType["unsigned"] = map[string]any{ "boolean": mysql.HasUnsignedFlag(col.GetFlag()), } - mysqlType["zerofill"] = map[string]interface{}{ + mysqlType["zerofill"] = map[string]any{ "boolean": mysql.HasZerofillFlag(col.GetFlag()), } case mysql.TypeEnum, mysql.TypeSet: - mysqlType["elements"] = map[string]interface{}{ + mysqlType["elements"] = map[string]any{ "array": col.GetElems(), } case mysql.TypeNewDecimal: - mysqlType["decimal"] = map[string]interface{}{ + mysqlType["decimal"] = map[string]any{ "int": col.GetDecimal(), } - mysqlType["unsigned"] = map[string]interface{}{ + mysqlType["unsigned"] = map[string]any{ "boolean": mysql.HasUnsignedFlag(col.GetFlag()), } - mysqlType["zerofill"] = map[string]interface{}{ + mysqlType["zerofill"] = map[string]any{ "boolean": mysql.HasZerofillFlag(col.GetFlag()), } default: } - column := map[string]interface{}{ + column := map[string]any{ "name": col.Name.O, "dataType": mysqlType, "nullable": !mysql.HasNotNullFlag(col.GetFlag()), @@ -112,7 +112,7 @@ func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { defaultValue := col.GetDefaultValue() if defaultValue != nil { // according to TiDB source code, the default value is converted to string if not nil. - column["default"] = map[string]interface{}{ + column["default"] = map[string]any{ "string": defaultValue, } } @@ -120,7 +120,7 @@ func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { columnsSchema = append(columnsSchema, column) } - result := map[string]interface{}{ + result := map[string]any{ "database": tableInfo.TableName.Schema, "table": tableInfo.TableName.Table, "tableID": tableInfo.ID, @@ -132,51 +132,51 @@ func newTableSchemaMap(tableInfo *model.TableInfo) interface{} { return result } -func newResolvedMessageMap(ts uint64) map[string]interface{} { - watermark := map[string]interface{}{ +func newResolvedMessageMap(ts uint64) map[string]any { + watermark := map[string]any{ "version": defaultVersion, "type": string(MessageTypeWatermark), "commitTs": int64(ts), "buildTs": time.Now().UnixMilli(), } - watermark = map[string]interface{}{ + watermark = map[string]any{ "com.pingcap.simple.avro.Watermark": watermark, } - payload := map[string]interface{}{ + payload := map[string]any{ "type": string(MessageTypeWatermark), "payload": watermark, } - return map[string]interface{}{ + return map[string]any{ "com.pingcap.simple.avro.Message": payload, } } -func newBootstrapMessageMap(tableInfo *model.TableInfo) map[string]interface{} { - m := map[string]interface{}{ +func newBootstrapMessageMap(tableInfo *model.TableInfo) map[string]any { + m := map[string]any{ "version": defaultVersion, "type": string(MessageTypeBootstrap), "tableSchema": newTableSchemaMap(tableInfo), "buildTs": time.Now().UnixMilli(), } - m = map[string]interface{}{ + m = map[string]any{ "com.pingcap.simple.avro.Bootstrap": m, } - payload := map[string]interface{}{ + payload := map[string]any{ "type": string(MessageTypeBootstrap), "payload": m, } - return map[string]interface{}{ + return map[string]any{ "com.pingcap.simple.avro.Message": payload, } } -func newDDLMessageMap(ddl *model.DDLEvent) map[string]interface{} { - result := map[string]interface{}{ +func newDDLMessageMap(ddl *model.DDLEvent) map[string]any { + result := map[string]any{ "version": defaultVersion, "type": string(getDDLType(ddl.Type)), "sql": ddl.Query, @@ -186,25 +186,25 @@ func newDDLMessageMap(ddl *model.DDLEvent) map[string]interface{} { if ddl.TableInfo != nil && ddl.TableInfo.TableInfo != nil { tableSchema := newTableSchemaMap(ddl.TableInfo) - result["tableSchema"] = map[string]interface{}{ + result["tableSchema"] = map[string]any{ "com.pingcap.simple.avro.TableSchema": tableSchema, } } if ddl.PreTableInfo != nil && ddl.PreTableInfo.TableInfo != nil { tableSchema := newTableSchemaMap(ddl.PreTableInfo) - result["preTableSchema"] = map[string]interface{}{ + result["preTableSchema"] = map[string]any{ "com.pingcap.simple.avro.TableSchema": tableSchema, } } - result = map[string]interface{}{ + result = map[string]any{ "com.pingcap.simple.avro.DDL": result, } - payload := map[string]interface{}{ + payload := map[string]any{ "type": string(MessageTypeDDL), "payload": result, } - return map[string]interface{}{ + return map[string]any{ "com.pingcap.simple.avro.Message": payload, } } @@ -213,32 +213,32 @@ var ( // genericMapPool return holder for each column and checksum genericMapPool = sync.Pool{ New: func() any { - return make(map[string]interface{}) + return make(map[string]any) }, } // rowMapPool return map for each row rowMapPool = sync.Pool{ New: func() any { - return make(map[string]interface{}) + return make(map[string]any) }, } dmlMessagePayloadPool = sync.Pool{ New: func() any { - return make(map[string]interface{}) + return make(map[string]any) }, } // dmlMessagePool return a map for the dml message dmlMessagePool = sync.Pool{ New: func() any { - return make(map[string]interface{}) + return make(map[string]any) }, } messageHolderPool = sync.Pool{ New: func() any { - return make(map[string]interface{}) + return make(map[string]any) }, } ) @@ -247,8 +247,8 @@ func (a *avroMarshaller) newDMLMessageMap( event *model.RowChangedEvent, onlyHandleKey bool, claimCheckFileName string, -) map[string]interface{} { - dmlMessagePayload := dmlMessagePayloadPool.Get().(map[string]interface{}) +) map[string]any { + dmlMessagePayload := dmlMessagePayloadPool.Get().(map[string]any) dmlMessagePayload["version"] = defaultVersion dmlMessagePayload["database"] = event.TableInfo.GetSchemaName() dmlMessagePayload["table"] = event.TableInfo.GetTableName() @@ -258,26 +258,26 @@ func (a *avroMarshaller) newDMLMessageMap( dmlMessagePayload["schemaVersion"] = int64(event.TableInfo.UpdateTS) if !a.config.LargeMessageHandle.Disabled() && onlyHandleKey { - dmlMessagePayload["handleKeyOnly"] = map[string]interface{}{ + dmlMessagePayload["handleKeyOnly"] = map[string]any{ "boolean": true, } } if a.config.LargeMessageHandle.EnableClaimCheck() && claimCheckFileName != "" { - dmlMessagePayload["claimCheckLocation"] = map[string]interface{}{ + dmlMessagePayload["claimCheckLocation"] = map[string]any{ "string": claimCheckFileName, } } if a.config.EnableRowChecksum && event.Checksum != nil { - cc := map[string]interface{}{ + cc := map[string]any{ "version": event.Checksum.Version, "corrupted": event.Checksum.Corrupted, "current": int64(event.Checksum.Current), "previous": int64(event.Checksum.Previous), } - holder := genericMapPool.Get().(map[string]interface{}) + holder := genericMapPool.Get().(map[string]any) holder["com.pingcap.simple.avro.Checksum"] = cc dmlMessagePayload["checksum"] = holder } @@ -298,36 +298,36 @@ func (a *avroMarshaller) newDMLMessageMap( dmlMessagePayload["type"] = string(DMLTypeUpdate) } - dmlMessagePayload = map[string]interface{}{ + dmlMessagePayload = map[string]any{ "com.pingcap.simple.avro.DML": dmlMessagePayload, } - dmlMessage := dmlMessagePool.Get().(map[string]interface{}) + dmlMessage := dmlMessagePool.Get().(map[string]any) dmlMessage["type"] = string(MessageTypeDML) dmlMessage["payload"] = dmlMessagePayload - messageHolder := messageHolderPool.Get().(map[string]interface{}) + messageHolder := messageHolderPool.Get().(map[string]any) messageHolder["com.pingcap.simple.avro.Message"] = dmlMessage return messageHolder } -func recycleMap(m map[string]interface{}) { - dmlMessage := m["com.pingcap.simple.avro.Message"].(map[string]interface{}) - dml := dmlMessage["payload"].(map[string]interface{})["com.pingcap.simple.avro.DML"].(map[string]interface{}) +func recycleMap(m map[string]any) { + dmlMessage := m["com.pingcap.simple.avro.Message"].(map[string]any) + dml := dmlMessage["payload"].(map[string]any)["com.pingcap.simple.avro.DML"].(map[string]any) checksum := dml["checksum"] if checksum != nil { - checksum := checksum.(map[string]interface{}) + checksum := checksum.(map[string]any) clear(checksum) genericMapPool.Put(checksum) } dataMap := dml["data"] if dataMap != nil { - dataMap := dataMap.(map[string]interface{})["map"].(map[string]interface{}) + dataMap := dataMap.(map[string]any)["map"].(map[string]any) for _, col := range dataMap { - colMap := col.(map[string]interface{}) + colMap := col.(map[string]any) clear(colMap) genericMapPool.Put(col) } @@ -337,9 +337,9 @@ func recycleMap(m map[string]interface{}) { oldDataMap := dml["old"] if oldDataMap != nil { - oldDataMap := oldDataMap.(map[string]interface{})["map"].(map[string]interface{}) + oldDataMap := oldDataMap.(map[string]any)["map"].(map[string]any) for _, col := range oldDataMap { - colMap := col.(map[string]interface{}) + colMap := col.(map[string]any) clear(colMap) genericMapPool.Put(col) } @@ -359,8 +359,8 @@ func recycleMap(m map[string]interface{}) { func (a *avroMarshaller) collectColumns( columns []*model.ColumnData, tableInfo *model.TableInfo, onlyHandleKey bool, -) map[string]interface{} { - result := rowMapPool.Get().(map[string]interface{}) +) map[string]any { + result := rowMapPool.Get().(map[string]any) for _, col := range columns { if col != nil { colFlag := tableInfo.ForceGetColumnFlagType(col.ColumnID) @@ -369,22 +369,22 @@ func (a *avroMarshaller) collectColumns( } colInfo := tableInfo.ForceGetColumnInfo(col.ColumnID) value, avroType := a.encodeValue4Avro(col.Value, &colInfo.FieldType) - holder := genericMapPool.Get().(map[string]interface{}) + holder := genericMapPool.Get().(map[string]any) holder[avroType] = value result[colInfo.Name.O] = holder } } - return map[string]interface{}{ + return map[string]any{ "map": result, } } -func newTableSchemaFromAvroNative(native map[string]interface{}) *TableSchema { - rawColumns := native["columns"].([]interface{}) +func newTableSchemaFromAvroNative(native map[string]any) *TableSchema { + rawColumns := native["columns"].([]any) columns := make([]*columnSchema, 0, len(rawColumns)) for _, raw := range rawColumns { - raw := raw.(map[string]interface{}) - rawDataType := raw["dataType"].(map[string]interface{}) + raw := raw.(map[string]any) + rawDataType := raw["dataType"].(map[string]any) var ( decimal int @@ -394,19 +394,19 @@ func newTableSchemaFromAvroNative(native map[string]interface{}) *TableSchema { ) if rawDataType["elements"] != nil { - rawElements := rawDataType["elements"].(map[string]interface{})["array"].([]interface{}) + rawElements := rawDataType["elements"].(map[string]any)["array"].([]any) for _, rawElement := range rawElements { elements = append(elements, rawElement.(string)) } } if rawDataType["decimal"] != nil { - decimal = int(rawDataType["decimal"].(map[string]interface{})["int"].(int32)) + decimal = int(rawDataType["decimal"].(map[string]any)["int"].(int32)) } if rawDataType["unsigned"] != nil { - unsigned = rawDataType["unsigned"].(map[string]interface{})["boolean"].(bool) + unsigned = rawDataType["unsigned"].(map[string]any)["boolean"].(bool) } if rawDataType["zerofill"] != nil { - zerofill = rawDataType["zerofill"].(map[string]interface{})["boolean"].(bool) + zerofill = rawDataType["zerofill"].(map[string]any)["boolean"].(bool) } dt := dataType{ @@ -420,11 +420,11 @@ func newTableSchemaFromAvroNative(native map[string]interface{}) *TableSchema { Zerofill: zerofill, } - var defaultValue interface{} + var defaultValue any rawDefault := raw["default"] switch v := rawDefault.(type) { case nil: - case map[string]interface{}: + case map[string]any: defaultValue = v["string"].(string) } @@ -437,11 +437,11 @@ func newTableSchemaFromAvroNative(native map[string]interface{}) *TableSchema { columns = append(columns, column) } - rawIndexes := native["indexes"].([]interface{}) + rawIndexes := native["indexes"].([]any) indexes := make([]*IndexSchema, 0, len(rawIndexes)) for _, raw := range rawIndexes { - raw := raw.(map[string]interface{}) - rawColumns := raw["columns"].([]interface{}) + raw := raw.(map[string]any) + rawColumns := raw["columns"].([]any) keyColumns := make([]string, 0, len(rawColumns)) for _, rawColumn := range rawColumns { keyColumns = append(keyColumns, rawColumn.(string)) @@ -465,13 +465,13 @@ func newTableSchemaFromAvroNative(native map[string]interface{}) *TableSchema { } } -func newMessageFromAvroNative(native interface{}, m *message) { - rawValues := native.(map[string]interface{})["com.pingcap.simple.avro.Message"].(map[string]interface{}) - rawPayload := rawValues["payload"].(map[string]interface{}) +func newMessageFromAvroNative(native any, m *message) { + rawValues := native.(map[string]any)["com.pingcap.simple.avro.Message"].(map[string]any) + rawPayload := rawValues["payload"].(map[string]any) rawMessage := rawPayload["com.pingcap.simple.avro.Watermark"] if rawMessage != nil { - rawValues = rawMessage.(map[string]interface{}) + rawValues = rawMessage.(map[string]any) m.Version = int(rawValues["version"].(int32)) m.Type = MessageTypeWatermark m.CommitTs = uint64(rawValues["commitTs"].(int64)) @@ -481,17 +481,17 @@ func newMessageFromAvroNative(native interface{}, m *message) { rawMessage = rawPayload["com.pingcap.simple.avro.Bootstrap"] if rawMessage != nil { - rawValues = rawMessage.(map[string]interface{}) + rawValues = rawMessage.(map[string]any) m.Version = int(rawValues["version"].(int32)) m.Type = MessageTypeBootstrap m.BuildTs = rawValues["buildTs"].(int64) - m.TableSchema = newTableSchemaFromAvroNative(rawValues["tableSchema"].(map[string]interface{})) + m.TableSchema = newTableSchemaFromAvroNative(rawValues["tableSchema"].(map[string]any)) return } rawMessage = rawPayload["com.pingcap.simple.avro.DDL"] if rawMessage != nil { - rawValues = rawMessage.(map[string]interface{}) + rawValues = rawMessage.(map[string]any) m.Version = int(rawValues["version"].(int32)) m.Type = MessageType(rawValues["type"].(string)) m.SQL = rawValues["sql"].(string) @@ -500,21 +500,21 @@ func newMessageFromAvroNative(native interface{}, m *message) { rawTableSchemaValues := rawValues["tableSchema"] if rawTableSchemaValues != nil { - rawTableSchema := rawTableSchemaValues.(map[string]interface{}) - rawTableSchema = rawTableSchema["com.pingcap.simple.avro.TableSchema"].(map[string]interface{}) + rawTableSchema := rawTableSchemaValues.(map[string]any) + rawTableSchema = rawTableSchema["com.pingcap.simple.avro.TableSchema"].(map[string]any) m.TableSchema = newTableSchemaFromAvroNative(rawTableSchema) } rawPreTableSchemaValue := rawValues["preTableSchema"] if rawPreTableSchemaValue != nil { - rawPreTableSchema := rawPreTableSchemaValue.(map[string]interface{}) - rawPreTableSchema = rawPreTableSchema["com.pingcap.simple.avro.TableSchema"].(map[string]interface{}) + rawPreTableSchema := rawPreTableSchemaValue.(map[string]any) + rawPreTableSchema = rawPreTableSchema["com.pingcap.simple.avro.TableSchema"].(map[string]any) m.PreTableSchema = newTableSchemaFromAvroNative(rawPreTableSchema) } return } - rawValues = rawPayload["com.pingcap.simple.avro.DML"].(map[string]interface{}) + rawValues = rawPayload["com.pingcap.simple.avro.DML"].(map[string]any) m.Type = MessageType(rawValues["type"].(string)) m.Version = int(rawValues["version"].(int32)) m.CommitTs = uint64(rawValues["commitTs"].(int64)) @@ -525,10 +525,10 @@ func newMessageFromAvroNative(native interface{}, m *message) { m.SchemaVersion = uint64(rawValues["schemaVersion"].(int64)) if rawValues["handleKeyOnly"] != nil { - m.HandleKeyOnly = rawValues["handleKeyOnly"].(map[string]interface{})["boolean"].(bool) + m.HandleKeyOnly = rawValues["handleKeyOnly"].(map[string]any)["boolean"].(bool) } if rawValues["claimCheckLocation"] != nil { - m.ClaimCheckLocation = rawValues["claimCheckLocation"].(map[string]interface{})["string"].(string) + m.ClaimCheckLocation = rawValues["claimCheckLocation"].(map[string]any)["string"].(string) } m.Checksum = newChecksum(rawValues) @@ -536,13 +536,13 @@ func newMessageFromAvroNative(native interface{}, m *message) { m.Old = newDataMap(rawValues["old"]) } -func newChecksum(raw map[string]interface{}) *checksum { +func newChecksum(raw map[string]any) *checksum { rawValue := raw["checksum"] if rawValue == nil { return nil } - rawChecksum := rawValue.(map[string]interface{}) - rawChecksum = rawChecksum["com.pingcap.simple.avro.Checksum"].(map[string]interface{}) + rawChecksum := rawValue.(map[string]any) + rawChecksum = rawChecksum["com.pingcap.simple.avro.Checksum"].(map[string]any) return &checksum{ Version: int(rawChecksum["version"].(int32)), Corrupted: rawChecksum["corrupted"].(bool), @@ -551,18 +551,18 @@ func newChecksum(raw map[string]interface{}) *checksum { } } -func newDataMap(rawValues interface{}) map[string]interface{} { +func newDataMap(rawValues any) map[string]any { if rawValues == nil { return nil } - data := make(map[string]interface{}) - rawDataMap := rawValues.(map[string]interface{})["map"].(map[string]interface{}) + data := make(map[string]any) + rawDataMap := rawValues.(map[string]any)["map"].(map[string]any) for key, value := range rawDataMap { if value == nil { data[key] = nil continue } - valueMap := value.(map[string]interface{}) + valueMap := value.(map[string]any) for _, v := range valueMap { data[key] = v } diff --git a/pkg/sink/codec/simple/decoder.go b/pkg/sink/codec/simple/decoder.go index 30101beca7..f9e1f9fe7d 100644 --- a/pkg/sink/codec/simple/decoder.go +++ b/pkg/sink/codec/simple/decoder.go @@ -244,11 +244,11 @@ func (d *Decoder) assembleHandleKeyOnlyRowChangedEvent(m *message) (*model.RowCh func (d *Decoder) buildData( holder *common.ColumnsHolder, fieldTypeMap map[string]*types.FieldType, timezone string, -) map[string]interface{} { +) map[string]any { columnsCount := holder.Length() - result := make(map[string]interface{}, columnsCount) + result := make(map[string]any, columnsCount) - for i := 0; i < columnsCount; i++ { + for i := range columnsCount { col := holder.Types[i] value := holder.Values[i] diff --git a/pkg/sink/codec/simple/encoder_test.go b/pkg/sink/codec/simple/encoder_test.go index d76c6ec25e..ef4f28f0b8 100644 --- a/pkg/sink/codec/simple/encoder_test.go +++ b/pkg/sink/codec/simple/encoder_test.go @@ -17,6 +17,7 @@ import ( "context" "database/sql/driver" "fmt" + "maps" "math/rand" "sort" "strconv" @@ -1485,7 +1486,7 @@ func TestEncodeLargeEventsNormal(t *testing.T) { require.NoError(t, err) require.NotNil(t, obtainedDDL) - obtainedDefaultValues := make(map[string]interface{}, len(obtainedDDL.TableInfo.Columns)) + obtainedDefaultValues := make(map[string]any, len(obtainedDDL.TableInfo.Columns)) for _, col := range obtainedDDL.TableInfo.Columns { obtainedDefaultValues[col.Name.O] = col.GetDefaultValue() switch col.GetType() { @@ -1790,10 +1791,8 @@ func TestLargeMessageHandleKeyOnly(t *testing.T) { require.Equal(t, model.MessageTypeRow, messageType) require.True(t, dec.msg.HandleKeyOnly) - obtainedValues := make(map[string]interface{}, len(dec.msg.Data)) - for name, value := range dec.msg.Data { - obtainedValues[name] = value - } + obtainedValues := make(map[string]any, len(dec.msg.Data)) + maps.Copy(obtainedValues, dec.msg.Data) for _, col := range event.Columns { colName := event.TableInfo.ForceGetColumnName(col.ColumnID) colFlag := event.TableInfo.ForceGetColumnFlagType(col.ColumnID) @@ -1813,9 +1812,7 @@ func TestLargeMessageHandleKeyOnly(t *testing.T) { } clear(obtainedValues) - for name, value := range dec.msg.Old { - obtainedValues[name] = value - } + maps.Copy(obtainedValues, dec.msg.Old) for _, col := range event.PreColumns { colName := event.TableInfo.ForceGetColumnName(col.ColumnID) colFlag := event.TableInfo.ForceGetColumnFlagType(col.ColumnID) diff --git a/pkg/sink/codec/simple/marshaller.go b/pkg/sink/codec/simple/marshaller.go index cac4a48c14..343c3ce32f 100644 --- a/pkg/sink/codec/simple/marshaller.go +++ b/pkg/sink/codec/simple/marshaller.go @@ -121,7 +121,7 @@ func (m *avroMarshaller) MarshalCheckpoint(ts uint64) ([]byte, error) { // MarshalDDLEvent implement the marshaller interface func (m *avroMarshaller) MarshalDDLEvent(event *model.DDLEvent) ([]byte, error) { - var msg map[string]interface{} + var msg map[string]any if event.IsBootstrap { msg = newBootstrapMessageMap(event.TableInfo) } else { diff --git a/pkg/sink/codec/simple/message.go b/pkg/sink/codec/simple/message.go index 4bba13e0e0..b5c2b1a2bb 100644 --- a/pkg/sink/codec/simple/message.go +++ b/pkg/sink/codec/simple/message.go @@ -102,10 +102,10 @@ func getDDLType(t timodel.ActionType) MessageType { // columnSchema is the schema of the column. type columnSchema struct { - Name string `json:"name"` - DataType dataType `json:"dataType"` - Nullable bool `json:"nullable"` - Default interface{} `json:"default"` + Name string `json:"name"` + DataType dataType `json:"dataType"` + Nullable bool `json:"nullable"` + Default any `json:"default"` } type dataType struct { @@ -428,7 +428,7 @@ func adjustTimestampValue(column *model.ColumnData, flag types.FieldType) { switch v := column.Value.(type) { case map[string]string: ts = v["value"] - case map[string]interface{}: + case map[string]any: ts = v["value"].(string) } column.Value = ts @@ -436,7 +436,7 @@ func adjustTimestampValue(column *model.ColumnData, flag types.FieldType) { } func decodeColumns( - rawData map[string]interface{}, tableInfo *model.TableInfo, + rawData map[string]any, tableInfo *model.TableInfo, ) []*model.ColumnData { if rawData == nil { return nil @@ -492,9 +492,9 @@ type message struct { Checksum *checksum `json:"checksum,omitempty"` // Data is available for the Insert and Update event. - Data map[string]interface{} `json:"data,omitempty"` + Data map[string]any `json:"data,omitempty"` // Old is available for the Update and Delete event. - Old map[string]interface{} `json:"old,omitempty"` + Old map[string]any `json:"old,omitempty"` // TableSchema is for the DDL and Bootstrap event. TableSchema *TableSchema `json:"tableSchema,omitempty"` // PreTableSchema holds schema information before the DDL executed. @@ -586,8 +586,8 @@ func (a *jsonMarshaller) newDMLMessage( func (a *jsonMarshaller) formatColumns( columns []*model.ColumnData, tableInfo *model.TableInfo, onlyHandleKey bool, -) map[string]interface{} { - result := make(map[string]interface{}, len(columns)) +) map[string]any { + result := make(map[string]any, len(columns)) colInfos := tableInfo.GetColInfosForRowChangedEvent() for i, col := range columns { if col != nil { @@ -603,21 +603,21 @@ func (a *jsonMarshaller) formatColumns( } func (a *avroMarshaller) encodeValue4Avro( - value interface{}, ft *types.FieldType, -) (interface{}, string) { + value any, ft *types.FieldType, +) (any, string) { if value == nil { return nil, "null" } switch ft.GetType() { case mysql.TypeTimestamp: - return map[string]interface{}{ + return map[string]any{ "location": a.config.TimeZone.String(), "value": value.(string), }, "com.pingcap.simple.avro.Timestamp" case mysql.TypeLonglong: if mysql.HasUnsignedFlag(ft.GetFlag()) { - return map[string]interface{}{ + return map[string]any{ "value": int64(value.(uint64)), }, "com.pingcap.simple.avro.UnsignedBigint" } @@ -648,8 +648,8 @@ func (a *avroMarshaller) encodeValue4Avro( } func encodeValue( - value interface{}, ft *types.FieldType, location string, -) interface{} { + value any, ft *types.FieldType, location string, +) any { if value == nil { return nil } @@ -725,7 +725,7 @@ func encodeValue( return result } -func decodeColumn(value interface{}, id int64, fieldType *types.FieldType) *model.ColumnData { +func decodeColumn(value any, id int64, fieldType *types.FieldType) *model.ColumnData { result := &model.ColumnData{ ColumnID: id, Value: value, @@ -784,7 +784,7 @@ func decodeColumn(value interface{}, id int64, fieldType *types.FieldType) *mode } else { value, err = strconv.ParseInt(v, 10, 64) } - case map[string]interface{}: + case map[string]any: value = uint64(v["value"].(int64)) default: value = v diff --git a/pkg/sink/codec/utils/test_utils.go b/pkg/sink/codec/utils/test_utils.go index 18c38c8918..c24408f6c8 100644 --- a/pkg/sink/codec/utils/test_utils.go +++ b/pkg/sink/codec/utils/test_utils.go @@ -165,7 +165,7 @@ func LargeColumnKeyValues() ([]string, []driver.Value) { } // LargeTableColumns is the columns of large table -var LargeTableColumns = map[string]interface{}{ +var LargeTableColumns = map[string]any{ "t": []uint8("127"), "tu1": []uint8("127"), "tu2": []uint8("128"), diff --git a/pkg/sink/kafka/options_test.go b/pkg/sink/kafka/options_test.go index c9b34bb580..10a3443cef 100644 --- a/pkg/sink/kafka/options_test.go +++ b/pkg/sink/kafka/options_test.go @@ -437,7 +437,7 @@ func TestCreateProducerFailed(t *testing.T) { func TestConfigurationCombinations(t *testing.T) { combinations := []struct { uriTemplate string - uriParams []interface{} + uriParams []any brokerMessageMaxBytes string topicMaxMessageBytes string expectedMaxMessageBytes string @@ -447,7 +447,7 @@ func TestConfigurationCombinations(t *testing.T) { // expected = min(`max-message-bytes`, `message.max.bytes`) = `message.max.bytes` { "kafka://127.0.0.1:9092/%s", - []interface{}{"not-exist-topic"}, + []any{"not-exist-topic"}, BrokerMessageMaxBytes, TopicMaxMessageBytes, BrokerMessageMaxBytes, @@ -457,7 +457,7 @@ func TestConfigurationCombinations(t *testing.T) { // expected = min(`max-message-bytes`, `message.max.bytes`) = `max-message-bytes` { "kafka://127.0.0.1:9092/%s", - []interface{}{"not-exist-topic"}, + []any{"not-exist-topic"}, strconv.Itoa(config.DefaultMaxMessageBytes), TopicMaxMessageBytes, strconv.Itoa(config.DefaultMaxMessageBytes), @@ -467,7 +467,7 @@ func TestConfigurationCombinations(t *testing.T) { // expected = min(`max-message-bytes`, `message.max.bytes`) = `max-message-bytes` { "kafka://127.0.0.1:9092/%s", - []interface{}{"no-params"}, + []any{"no-params"}, strconv.Itoa(config.DefaultMaxMessageBytes + 1), TopicMaxMessageBytes, strconv.Itoa(config.DefaultMaxMessageBytes), @@ -477,7 +477,7 @@ func TestConfigurationCombinations(t *testing.T) { // user set `max-message-bytes` < `message.max.bytes` < default `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{"not-created-topic", strconv.Itoa(1024*1024 - 1)}, + []any{"not-created-topic", strconv.Itoa(1024*1024 - 1)}, BrokerMessageMaxBytes, TopicMaxMessageBytes, strconv.Itoa(1024*1024 - 1), @@ -486,7 +486,7 @@ func TestConfigurationCombinations(t *testing.T) { // user set `max-message-bytes` < default `max-message-bytes` < `message.max.bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes - 1)}, + []any{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes - 1)}, strconv.Itoa(config.DefaultMaxMessageBytes + 1), TopicMaxMessageBytes, strconv.Itoa(config.DefaultMaxMessageBytes - 1), @@ -495,7 +495,7 @@ func TestConfigurationCombinations(t *testing.T) { // `message.max.bytes` < user set `max-message-bytes` < default `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{"not-created-topic", strconv.Itoa(1024*1024 + 1)}, + []any{"not-created-topic", strconv.Itoa(1024*1024 + 1)}, BrokerMessageMaxBytes, TopicMaxMessageBytes, BrokerMessageMaxBytes, @@ -504,7 +504,7 @@ func TestConfigurationCombinations(t *testing.T) { // `message.max.bytes` < default `max-message-bytes` < user set `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes + 1)}, + []any{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes + 1)}, BrokerMessageMaxBytes, TopicMaxMessageBytes, BrokerMessageMaxBytes, @@ -513,7 +513,7 @@ func TestConfigurationCombinations(t *testing.T) { // default `max-message-bytes` < user set `max-message-bytes` < `message.max.bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes + 1)}, + []any{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes + 1)}, strconv.Itoa(config.DefaultMaxMessageBytes + 2), TopicMaxMessageBytes, strconv.Itoa(config.DefaultMaxMessageBytes + 1), @@ -522,7 +522,7 @@ func TestConfigurationCombinations(t *testing.T) { // default `max-message-bytes` < `message.max.bytes` < user set `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes + 2)}, + []any{"not-created-topic", strconv.Itoa(config.DefaultMaxMessageBytes + 2)}, strconv.Itoa(config.DefaultMaxMessageBytes + 1), TopicMaxMessageBytes, strconv.Itoa(config.DefaultMaxMessageBytes + 1), @@ -533,7 +533,7 @@ func TestConfigurationCombinations(t *testing.T) { // expected = min(`max-message-bytes`, `max.message.bytes`) = `max.message.bytes` { "kafka://127.0.0.1:9092/%s", - []interface{}{DefaultMockTopicName}, + []any{DefaultMockTopicName}, BrokerMessageMaxBytes, TopicMaxMessageBytes, TopicMaxMessageBytes, @@ -543,7 +543,7 @@ func TestConfigurationCombinations(t *testing.T) { // expected = min(`max-message-bytes`, `max.message.bytes`) = `max-message-bytes` { "kafka://127.0.0.1:9092/%s", - []interface{}{DefaultMockTopicName}, + []any{DefaultMockTopicName}, BrokerMessageMaxBytes, strconv.Itoa(config.DefaultMaxMessageBytes), strconv.Itoa(config.DefaultMaxMessageBytes), @@ -553,7 +553,7 @@ func TestConfigurationCombinations(t *testing.T) { // expected = min(`max-message-bytes`, `max.message.bytes`) = `max-message-bytes` { "kafka://127.0.0.1:9092/%s", - []interface{}{DefaultMockTopicName}, + []any{DefaultMockTopicName}, BrokerMessageMaxBytes, strconv.Itoa(config.DefaultMaxMessageBytes + 1), strconv.Itoa(config.DefaultMaxMessageBytes), @@ -563,7 +563,7 @@ func TestConfigurationCombinations(t *testing.T) { // user set `max-message-bytes` < `max.message.bytes` < default `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{DefaultMockTopicName, strconv.Itoa(1024*1024 - 1)}, + []any{DefaultMockTopicName, strconv.Itoa(1024*1024 - 1)}, BrokerMessageMaxBytes, TopicMaxMessageBytes, strconv.Itoa(1024*1024 - 1), @@ -572,7 +572,7 @@ func TestConfigurationCombinations(t *testing.T) { // user set `max-message-bytes` < default `max-message-bytes` < `max.message.bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{ + []any{ DefaultMockTopicName, strconv.Itoa(config.DefaultMaxMessageBytes - 1), }, @@ -584,7 +584,7 @@ func TestConfigurationCombinations(t *testing.T) { // `max.message.bytes` < user set `max-message-bytes` < default `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{DefaultMockTopicName, strconv.Itoa(1024*1024 + 1)}, + []any{DefaultMockTopicName, strconv.Itoa(1024*1024 + 1)}, BrokerMessageMaxBytes, TopicMaxMessageBytes, TopicMaxMessageBytes, @@ -593,7 +593,7 @@ func TestConfigurationCombinations(t *testing.T) { // `max.message.bytes` < default `max-message-bytes` < user set `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{ + []any{ DefaultMockTopicName, strconv.Itoa(config.DefaultMaxMessageBytes + 1), }, @@ -605,7 +605,7 @@ func TestConfigurationCombinations(t *testing.T) { // default `max-message-bytes` < user set `max-message-bytes` < `max.message.bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{ + []any{ DefaultMockTopicName, strconv.Itoa(config.DefaultMaxMessageBytes + 1), }, @@ -617,7 +617,7 @@ func TestConfigurationCombinations(t *testing.T) { // default `max-message-bytes` < `max.message.bytes` < user set `max-message-bytes` { "kafka://127.0.0.1:9092/%s?max-message-bytes=%s", - []interface{}{ + []any{ DefaultMockTopicName, strconv.Itoa(config.DefaultMaxMessageBytes + 2), }, diff --git a/pkg/sink/kafka/sarama_test.go b/pkg/sink/kafka/sarama_test.go index 97136db65e..81547241ad 100644 --- a/pkg/sink/kafka/sarama_test.go +++ b/pkg/sink/kafka/sarama_test.go @@ -303,7 +303,6 @@ func TestApplySASL(t *testing.T) { } for _, test := range tests { - test := test t.Run(test.name, func(t *testing.T) { t.Parallel() options := NewOptions() @@ -374,7 +373,6 @@ func TestApplyTLS(t *testing.T) { } for _, test := range tests { - test := test t.Run(test.name, func(t *testing.T) { t.Parallel() options := NewOptions() diff --git a/pkg/sink/observer/observer_test.go b/pkg/sink/observer/observer_test.go index 225218f2ec..fb691da7e3 100644 --- a/pkg/sink/observer/observer_test.go +++ b/pkg/sink/observer/observer_test.go @@ -14,6 +14,7 @@ package observer import ( + context0 "context" "database/sql" "testing" @@ -23,7 +24,6 @@ import ( "github.com/pingcap/tiflow/pkg/config" pmysql "github.com/pingcap/tiflow/pkg/sink/mysql" "github.com/stretchr/testify/require" - "golang.org/x/net/context" ) func newTestMockDB(t *testing.T) (db *sql.DB, mock sqlmock.Sqlmock) { @@ -40,7 +40,7 @@ func TestNewObserver(t *testing.T) { t.Parallel() dbIndex := 0 - mockGetDBConn := func(ctx context.Context, dsnStr string) (*sql.DB, error) { + mockGetDBConn := func(ctx context0.Context, dsnStr string) (*sql.DB, error) { defer func() { dbIndex++ }() if dbIndex == 0 { @@ -57,13 +57,13 @@ func TestNewObserver(t *testing.T) { return db, nil } - ctx := context.Background() + ctx := context0.Background() sinkURI := "mysql://127.0.0.1:21347/" obs, err := NewObserver(ctx, model.DefaultChangeFeedID("test"), sinkURI, config.GetDefaultReplicaConfig(), WithDBConnFactory(mockGetDBConn)) require.NoError(t, err) - for i := 0; i < 10; i++ { + for range 10 { err = obs.Tick(ctx) require.NoError(t, err) } diff --git a/pkg/sink/observer/tidb.go b/pkg/sink/observer/tidb.go index 8a39faca83..5355a7bf27 100644 --- a/pkg/sink/observer/tidb.go +++ b/pkg/sink/observer/tidb.go @@ -186,8 +186,8 @@ type tidbConnIdleDuration struct { duration sql.NullFloat64 } -func (m *tidbConnIdleDuration) columns() []interface{} { - return []interface{}{&m.ts, &m.instance, &m.inTxn, &m.quantile, &m.duration} +func (m *tidbConnIdleDuration) columns() []any { + return []any{&m.ts, &m.instance, &m.inTxn, &m.quantile, &m.duration} } type tidbConnCount struct { @@ -196,8 +196,8 @@ type tidbConnCount struct { count sql.NullInt32 } -func (m *tidbConnCount) columns() []interface{} { - return []interface{}{&m.ts, &m.instance, &m.count} +func (m *tidbConnCount) columns() []any { + return []any{&m.ts, &m.instance, &m.count} } type tidbQueryDuration struct { @@ -207,8 +207,8 @@ type tidbQueryDuration struct { duration sql.NullFloat64 } -func (m *tidbQueryDuration) columns() []interface{} { - return []interface{}{&m.ts, &m.instance, &m.queryType, &m.duration} +func (m *tidbQueryDuration) columns() []any { + return []any{&m.ts, &m.instance, &m.queryType, &m.duration} } type tidbTxnDuration struct { @@ -218,8 +218,8 @@ type tidbTxnDuration struct { duration sql.NullFloat64 } -func (m *tidbTxnDuration) columns() []interface{} { - return []interface{}{&m.ts, &m.instance, &m.opType, &m.duration} +func (m *tidbTxnDuration) columns() []any { + return []any{&m.ts, &m.instance, &m.opType, &m.duration} } type metricColumnImpl interface { @@ -228,7 +228,7 @@ type metricColumnImpl interface { type metricColumnIface[T metricColumnImpl] interface { *T - columns() []interface{} + columns() []any } func queryMetrics[T metricColumnImpl, F metricColumnIface[T]]( diff --git a/pkg/sink/pulsar/logger.go b/pkg/sink/pulsar/logger.go index 2b07ece570..e5a31717bc 100644 --- a/pkg/sink/pulsar/logger.go +++ b/pkg/sink/pulsar/logger.go @@ -38,7 +38,7 @@ func (p *Logger) WithFields(fields log.Fields) log.Entry { } // WithField with field -func (p *Logger) WithField(name string, value interface{}) log.Entry { +func (p *Logger) WithField(name string, value any) log.Entry { return &Logger{p.zapLogger.With(zap.Any(name, value))} } @@ -48,42 +48,42 @@ func (p *Logger) WithError(err error) log.Entry { } // Debug debug -func (p *Logger) Debug(args ...interface{}) { +func (p *Logger) Debug(args ...any) { p.zapLogger.Sugar().Debug(args...) } // Info info -func (p *Logger) Info(args ...interface{}) { +func (p *Logger) Info(args ...any) { p.zapLogger.Sugar().Info(args...) } // Warn warn -func (p *Logger) Warn(args ...interface{}) { +func (p *Logger) Warn(args ...any) { p.zapLogger.Sugar().Warn(args...) } // Error error -func (p *Logger) Error(args ...interface{}) { +func (p *Logger) Error(args ...any) { p.zapLogger.Sugar().Error(args...) } // Debugf debugf -func (p *Logger) Debugf(format string, args ...interface{}) { +func (p *Logger) Debugf(format string, args ...any) { p.zapLogger.Sugar().Debugf(format, args...) } // Infof infof -func (p *Logger) Infof(format string, args ...interface{}) { +func (p *Logger) Infof(format string, args ...any) { p.zapLogger.Sugar().Infof(format, args...) } // Warnf warnf -func (p *Logger) Warnf(format string, args ...interface{}) { +func (p *Logger) Warnf(format string, args ...any) { p.zapLogger.Sugar().Warnf(format, args...) } // Errorf errorf -func (p *Logger) Errorf(format string, args ...interface{}) { +func (p *Logger) Errorf(format string, args ...any) { p.zapLogger.Sugar().Errorf(format, args...) } diff --git a/pkg/spanz/btree_map_test.go b/pkg/spanz/btree_map_test.go index dc5d4aeb8e..647529808f 100644 --- a/pkg/spanz/btree_map_test.go +++ b/pkg/spanz/btree_map_test.go @@ -78,7 +78,7 @@ func TestMapAscend(t *testing.T) { t.Parallel() m := NewBtreeMap[int]() - for i := 0; i < 4; i++ { + for i := range 4 { m.ReplaceOrInsert(tablepb.Span{TableID: int64(i)}, i) } diff --git a/pkg/spanz/convert.go b/pkg/spanz/convert.go index 442f6ad736..94b8dcb03d 100644 --- a/pkg/spanz/convert.go +++ b/pkg/spanz/convert.go @@ -17,6 +17,7 @@ import ( "fmt" "reflect" "sort" + "strings" "unsafe" "github.com/pingcap/log" @@ -27,11 +28,11 @@ import ( // HexKey returns a hex string generated from the key. func HexKey(key []byte) string { // TODO(qupeng): improve the function. - str := "" + var str strings.Builder for _, c := range key { - str += fmt.Sprintf("%02X", c) + str.WriteString(fmt.Sprintf("%02X", c)) } - return str + return str.String() } // ArrayToSpan converts an array of TableID to an array of Span. diff --git a/pkg/spanz/convert_test.go b/pkg/spanz/convert_test.go index f3e7c8db8b..6c797334af 100644 --- a/pkg/spanz/convert_test.go +++ b/pkg/spanz/convert_test.go @@ -34,7 +34,7 @@ func TestHashableSpan(t *testing.T) { func TestHashableSpanHeapAlloc(t *testing.T) { span := tablepb.Span{TableID: 1} - for i := 0; i < 10; i++ { + for i := range 10 { span.StartKey = append(span.StartKey, byte(i)) span.EndKey = append(span.EndKey, byte(i)) } diff --git a/pkg/spanz/hash_map_test.go b/pkg/spanz/hash_map_test.go index ea9d8b3827..f2ebf7fcbe 100644 --- a/pkg/spanz/hash_map_test.go +++ b/pkg/spanz/hash_map_test.go @@ -74,7 +74,7 @@ func TestHashMapIter(t *testing.T) { t.Parallel() m := NewHashMap[int]() - for i := 0; i < 4; i++ { + for i := range 4 { m.ReplaceOrInsert(tablepb.Span{TableID: int64(i)}, i) } diff --git a/pkg/spanz/map_bench_test.go b/pkg/spanz/map_bench_test.go index 96335245ee..d7c71f1dba 100644 --- a/pkg/spanz/map_bench_test.go +++ b/pkg/spanz/map_bench_test.go @@ -25,7 +25,7 @@ func BenchmarkMap(b *testing.B) { sm := SyncMap{} spans := [100]tablepb.Span{} - for i := 0; i < len(spans); i++ { + for i := range len(spans) { spans[i] = TableIDToComparableSpan(int64(i)) } for i, span := range spans { diff --git a/pkg/sqlmodel/causality.go b/pkg/sqlmodel/causality.go index b2c60f0b1b..725b71a387 100644 --- a/pkg/sqlmodel/causality.go +++ b/pkg/sqlmodel/causality.go @@ -57,7 +57,7 @@ func collationNeeds2LowerCase(collation string) bool { return strings.HasSuffix(collation, "_ci") } -func columnValue2String(value interface{}) string { +func columnValue2String(value any) string { var data string switch v := value.(type) { case nil: @@ -104,7 +104,7 @@ func columnValue2String(value interface{}) string { func genKeyString( table string, columns []*timodel.ColumnInfo, - values []interface{}, + values []any, ) string { var buf strings.Builder for i, data := range values { @@ -140,9 +140,9 @@ func truncateIndexValues( ti *timodel.TableInfo, indexColumns *timodel.IndexInfo, tiColumns []*timodel.ColumnInfo, - data []interface{}, -) []interface{} { - values := make([]interface{}, 0, len(indexColumns.Columns)) + data []any, +) []any { + values := make([]any, 0, len(indexColumns.Columns)) datums, err := utils.AdjustBinaryProtocolForDatum(ctx, data, tiColumns) if err != nil { log.L().Warn("adjust binary protocol for datum error", zap.Error(err)) @@ -155,7 +155,7 @@ func truncateIndexValues( return values } -func (r *RowChange) getForeignKeyCausalityString(values []interface{}) []string { +func (r *RowChange) getForeignKeyCausalityString(values []any) []string { if len(r.foreignKeyRelations) == 0 { return nil } @@ -167,7 +167,7 @@ func (r *RowChange) getForeignKeyCausalityString(values []interface{}) []string continue } - relationValues := make([]interface{}, len(relation.ChildColumnIdx)) + relationValues := make([]any, len(relation.ChildColumnIdx)) skip := false for i, idx := range relation.ChildColumnIdx { if idx >= len(values) { @@ -200,7 +200,7 @@ func (r *RowChange) getForeignKeyCausalityString(values []interface{}) []string return keys } -func (r *RowChange) getCausalityString(values []interface{}) []string { +func (r *RowChange) getCausalityString(values []any) []string { sourceTable := r.sourceTable if r.causalityKeySourceTable != nil { // Only causality keys use this table name; r.sourceTable keeps the original source table. diff --git a/pkg/sqlmodel/causality_fk_test.go b/pkg/sqlmodel/causality_fk_test.go index dfce7685ef..a08e9dc4eb 100644 --- a/pkg/sqlmodel/causality_fk_test.go +++ b/pkg/sqlmodel/causality_fk_test.go @@ -38,7 +38,7 @@ func TestCausalityKeysWithForeignKey(t *testing.T) { &cdcmodel.TableName{Schema: "db", Table: "b"}, nil, nil, - []interface{}{2, 10}, + []any{2, 10}, childTable, nil, nil, @@ -65,7 +65,7 @@ func TestCausalityKeysWithNullForeignKey(t *testing.T) { &cdcmodel.TableName{Schema: "db", Table: "b"}, nil, nil, - []interface{}{3, nil}, + []any{3, nil}, childTable, nil, nil, diff --git a/pkg/sqlmodel/causality_test.go b/pkg/sqlmodel/causality_test.go index 0d17161191..348f104964 100644 --- a/pkg/sqlmodel/causality_test.go +++ b/pkg/sqlmodel/causality_test.go @@ -28,28 +28,28 @@ func TestCausalityKeys(t *testing.T) { cases := []struct { createSQL string - preValue []interface{} - postValue []interface{} + preValue []any + postValue []any causalityKeys []string }{ { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT, c3 VARCHAR(10) UNIQUE)", - []interface{}{1, 2, "abc"}, - []interface{}{3, 4, "abc"}, + []any{1, 2, "abc"}, + []any{3, 4, "abc"}, []string{"abc.c3.db.tb1", "1.c.db.tb1", "abc.c3.db.tb1", "3.c.db.tb1"}, }, { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT, c3 VARCHAR(10), UNIQUE INDEX(c3(1)))", - []interface{}{1, 2, "abc"}, - []interface{}{3, 4, "adef"}, + []any{1, 2, "abc"}, + []any{3, 4, "adef"}, []string{"a.c3.db.tb1", "1.c.db.tb1", "a.c3.db.tb1", "3.c.db.tb1"}, }, // test not string key { "CREATE TABLE tb1 (a INT, b INT, UNIQUE KEY a(a))", - []interface{}{100, 200}, + []any{100, 200}, nil, []string{"100.a.db.tb1"}, }, @@ -57,7 +57,7 @@ func TestCausalityKeys(t *testing.T) { // test text { "CREATE TABLE tb1 (a INT, b TEXT, UNIQUE KEY b(b(3)))", - []interface{}{1, "1234"}, + []any{1, "1234"}, nil, []string{"123.b.db.tb1"}, }, @@ -65,7 +65,7 @@ func TestCausalityKeys(t *testing.T) { // test composite keys { "CREATE TABLE tb1 (a INT, b TEXT, UNIQUE KEY c2(a, b(3)))", - []interface{}{1, "1234"}, + []any{1, "1234"}, nil, []string{"1.a.123.b.db.tb1"}, }, @@ -73,7 +73,7 @@ func TestCausalityKeys(t *testing.T) { // test value is null { "CREATE TABLE tb1 (a INT, b TEXT, UNIQUE KEY c2(a, b(3)))", - []interface{}{1, nil}, + []any{1, nil}, nil, []string{"1.a.db.tb1"}, }, @@ -92,7 +92,7 @@ func TestCausalityKeysWithCausalityKeySourceTable(t *testing.T) { source := &cdcmodel.TableName{Schema: "DB", Table: "Parent"} causalityKeySource := &cdcmodel.TableName{Schema: "db", Table: "parent"} ti := mockTableInfo(t, "CREATE TABLE parent (id INT PRIMARY KEY)") - change := NewRowChange(source, nil, nil, []interface{}{10}, ti, nil, nil) + change := NewRowChange(source, nil, nil, []any{10}, ti, nil, nil) change.SetCausalityKeySourceTable(causalityKeySource) require.Equal(t, []string{"10.id.db.parent"}, change.CausalityKeys()) @@ -105,13 +105,11 @@ func TestCausalityKeysNoRace(t *testing.T) { source := &cdcmodel.TableName{Schema: "db", Table: "tb1"} ti := mockTableInfo(t, "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT, c3 VARCHAR(10) UNIQUE)") var wg sync.WaitGroup - for i := 0; i < 100; i++ { - wg.Add(1) - go func() { - change := NewRowChange(source, nil, []interface{}{1, 2, "abc"}, []interface{}{3, 4, "abc"}, ti, nil, nil) + for range 100 { + wg.Go(func() { + change := NewRowChange(source, nil, []any{1, 2, "abc"}, []any{3, 4, "abc"}, ti, nil, nil) change.CausalityKeys() - wg.Done() - }() + }) } wg.Wait() } @@ -123,73 +121,73 @@ func TestGetCausalityString(t *testing.T) { testCases := []struct { schema string - values []interface{} + values []any keys []string }{ { // test no keys will use full row data instead of table name schema: `create table t1(a int)`, - values: []interface{}{10}, + values: []any{10}, keys: []string{"10.a.db.tbl"}, }, { // one primary key schema: `create table t2(a int primary key, b double)`, - values: []interface{}{60, 70.5}, + values: []any{60, 70.5}, keys: []string{"60.a.db.tbl"}, }, { // one unique key schema: `create table t3(a int unique, b double)`, - values: []interface{}{60, 70.5}, + values: []any{60, 70.5}, keys: []string{"60.a.db.tbl"}, }, { // one ordinary key schema: `create table t4(a int, b double, key(b))`, - values: []interface{}{60, 70.5}, + values: []any{60, 70.5}, keys: []string{"60.a.70.5.b.db.tbl"}, }, { // multiple keys schema: `create table t5(a int, b text, c int, key(a), key(b(3)))`, - values: []interface{}{13, "abcdef", 15}, + values: []any{13, "abcdef", 15}, keys: []string{"13.a.abcdef.b.15.c.db.tbl"}, }, { // multiple keys with primary key schema: `create table t6(a int primary key, b varchar(16) unique)`, - values: []interface{}{16, "xyz"}, + values: []any{16, "xyz"}, keys: []string{"xyz.b.db.tbl", "16.a.db.tbl"}, }, { // non-integer primary key schema: `create table t65(a int unique, b varchar(16) primary key)`, - values: []interface{}{16, "xyz"}, + values: []any{16, "xyz"}, keys: []string{"16.a.db.tbl", "xyz.b.db.tbl"}, }, { // case insensitive schema: `create table t_ci(a int unique, b varchar(16) primary key)default charset=utf8 collate=utf8_unicode_ci`, - values: []interface{}{16, "XyZ"}, + values: []any{16, "XyZ"}, keys: []string{"16.a.db.tbl", "xyz.b.db.tbl"}, }, { // case sensitive schema: `create table t_bin(a int unique, b varchar(16) primary key)default charset=utf8 collate=utf8_bin`, - values: []interface{}{16, "XyZ"}, + values: []any{16, "XyZ"}, keys: []string{"16.a.db.tbl", "XyZ.b.db.tbl"}, }, { // primary key of multiple columns schema: `create table t7(a int, b int, primary key(a, b))`, - values: []interface{}{59, 69}, + values: []any{59, 69}, keys: []string{"59.a.69.b.db.tbl"}, }, { // ordinary key of multiple columns schema: `create table t75(a int, b int, c int, key(a, b), key(c, b))`, - values: []interface{}{48, 58, 68}, + values: []any{48, 58, 68}, keys: []string{"48.a.58.b.68.c.db.tbl"}, }, { @@ -203,7 +201,7 @@ func TestGetCausalityString(t *testing.T) { unique key(c, a) ) `, - values: []interface{}{27, 37, 47}, + values: []any{27, 37, 47}, keys: []string{"27.a.37.b.db.tbl", "37.b.47.c.db.tbl", "47.c.27.a.db.tbl"}, }, { @@ -215,7 +213,7 @@ func TestGetCausalityString(t *testing.T) { unique key(b) ) `, - values: []interface{}{17, nil}, + values: []any{17, nil}, keys: []string{"17.a.db.tbl"}, }, } diff --git a/pkg/sqlmodel/multirow.go b/pkg/sqlmodel/multirow.go index b3dbfb8059..1d9ab5b285 100644 --- a/pkg/sqlmodel/multirow.go +++ b/pkg/sqlmodel/multirow.go @@ -76,7 +76,7 @@ func SameTypeTargetAndColumns(lhs *RowChange, rhs *RowChange) bool { // GenDeleteSQL generates the DELETE SQL and its arguments. // Input `changes` should have same target table and same columns for WHERE // (typically same PK/NOT NULL UK), otherwise the behaviour is undefined. -func GenDeleteSQL(changes ...*RowChange) (string, []interface{}) { +func GenDeleteSQL(changes ...*RowChange) (string, []any) { if len(changes) == 0 { log.L().DPanic("row changes is empty") return "", nil @@ -90,7 +90,7 @@ func GenDeleteSQL(changes ...*RowChange) (string, []interface{}) { buf.WriteString(first.targetTable.QuoteString()) buf.WriteString(" WHERE (") - allArgs := make([]interface{}, 0, len(changes)*CommonIndexColumnsCount) + allArgs := make([]any, 0, len(changes)*CommonIndexColumnsCount) for i, c := range changes { if i > 0 { @@ -123,7 +123,7 @@ func GenUpdateSQL(changes ...*RowChange) (string, []any) { // Pre-generate essential sub statements used after WHEN, WHERE. var ( whenCaseStmts = make([]string, len(changes)) - whenCaseArgs = make([][]interface{}, len(changes)) + whenCaseArgs = make([][]any, len(changes)) ) whereColumns, _ := first.whereColumnsAndValues() @@ -226,7 +226,7 @@ func GenUpdateSQL(changes ...*RowChange) (string, []any) { // GenInsertSQL generates the INSERT SQL and its arguments. // Input `changes` should have same target table and same modifiable columns, // otherwise the behaviour is undefined. -func GenInsertSQL(tp DMLType, changes ...*RowChange) (string, []interface{}) { +func GenInsertSQL(tp DMLType, changes ...*RowChange) (string, []any) { if len(changes) == 0 { log.L().DPanic("row changes is empty") return "", nil @@ -289,7 +289,7 @@ func GenInsertSQL(tp DMLType, changes ...*RowChange) (string, []interface{}) { } } - args := make([]interface{}, 0, len(changes)*(len(first.sourceTableInfo.Columns)-len(skipColIdx))) + args := make([]any, 0, len(changes)*(len(first.sourceTableInfo.Columns)-len(skipColIdx))) for _, change := range changes { i := 0 // used as index of skipColIdx for j, val := range change.postValues { diff --git a/pkg/sqlmodel/multirow_bench_test.go b/pkg/sqlmodel/multirow_bench_test.go index 507cec5dc3..e59632f37c 100644 --- a/pkg/sqlmodel/multirow_bench_test.go +++ b/pkg/sqlmodel/multirow_bench_test.go @@ -31,10 +31,10 @@ func prepareDataOneColoumnPK(t *testing.T, batch int) []*RowChange { c4 VARCHAR(10), c5 VARCHAR(100), c6 VARCHAR(1000), PRIMARY KEY (c))`) changes := make([]*RowChange, 0, batch) - for i := 0; i < batch; i++ { + for i := range batch { change := NewRowChange(source, target, - []interface{}{i + 1, i + 2, i + 3, "c4", "c5", "c6"}, - []interface{}{i + 10, i + 20, i + 30, "c4", "c5", "c6"}, + []any{i + 1, i + 2, i + 3, "c4", "c5", "c6"}, + []any{i + 10, i + 20, i + 30, "c4", "c5", "c6"}, sourceTI, targetTI, nil) changes = append(changes, change) } @@ -53,10 +53,10 @@ func prepareDataMultiColumnsPK(t *testing.T, batch int) []*RowChange { PRIMARY KEY (c1, c2, c3, c4))`) changes := make([]*RowChange, 0, batch) - for i := 0; i < batch; i++ { + for i := range batch { change := NewRowChange(source, target, - []interface{}{i + 1, i + 2, i + 3, i + 4, "c4", "c5", "c6", "c7", time.Time{}, time.Time{}}, - []interface{}{i + 10, i + 20, i + 30, i + 40, "c4", "c5", "c6", "c7", time.Time{}, time.Time{}}, + []any{i + 1, i + 2, i + 3, i + 4, "c4", "c5", "c6", "c7", time.Time{}, time.Time{}}, + []any{i + 10, i + 20, i + 30, i + 40, "c4", "c5", "c6", "c7", time.Time{}, time.Time{}}, sourceTI, targetTI, nil) changes = append(changes, change) } diff --git a/pkg/sqlmodel/multirow_test.go b/pkg/sqlmodel/multirow_test.go index 215a1d7f00..c8718e807a 100644 --- a/pkg/sqlmodel/multirow_test.go +++ b/pkg/sqlmodel/multirow_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/require" ) -type genSQLFunc func(changes ...*RowChange) (string, []interface{}) +type genSQLFunc func(changes ...*RowChange) (string, []any) func TestGenDeleteMultiRows(t *testing.T) { t.Parallel() @@ -33,12 +33,12 @@ func TestGenDeleteMultiRows(t *testing.T) { sourceTI2 := mockTableInfo(t, "CREATE TABLE tb2 (c INT PRIMARY KEY, c2 INT)") targetTI := mockTableInfo(t, "CREATE TABLE tb (c INT PRIMARY KEY, c2 INT)") - change1 := NewRowChange(source1, target, []interface{}{1, 2}, nil, sourceTI1, targetTI, nil) - change2 := NewRowChange(source2, target, []interface{}{3, 4}, nil, sourceTI2, targetTI, nil) + change1 := NewRowChange(source1, target, []any{1, 2}, nil, sourceTI1, targetTI, nil) + change2 := NewRowChange(source2, target, []any{3, 4}, nil, sourceTI2, targetTI, nil) sql, args := GenDeleteSQL(change1, change2) require.Equal(t, "DELETE FROM `db`.`tb` WHERE (`c` = ?) OR (`c` = ?)", sql) - require.Equal(t, []interface{}{1, 3}, args) + require.Equal(t, []any{1, 3}, args) } func TestGenUpdateMultiRows(t *testing.T) { @@ -71,8 +71,8 @@ func testGenUpdateMultiRows(t *testing.T, genUpdate genSQLFunc) { sourceTI2 := mockTableInfo(t, "CREATE TABLE tb2 (c INT, c2 INT, c3 INT, UNIQUE KEY (c, c2))") targetTI := mockTableInfo(t, "CREATE TABLE tb (c INT, c2 INT, c3 INT, UNIQUE KEY (c, c2))") - change1 := NewRowChange(source1, target, []interface{}{1, 2, 3}, []interface{}{10, 20, 30}, sourceTI1, targetTI, nil) - change2 := NewRowChange(source2, target, []interface{}{4, 5, 6}, []interface{}{40, 50, 60}, sourceTI2, targetTI, nil) + change1 := NewRowChange(source1, target, []any{1, 2, 3}, []any{10, 20, 30}, sourceTI1, targetTI, nil) + change2 := NewRowChange(source2, target, []any{4, 5, 6}, []any{40, 50, 60}, sourceTI2, targetTI, nil) sql, args := genUpdate(change1, change2) expectedSQL := "UPDATE `db`.`tb` SET " + @@ -80,7 +80,7 @@ func testGenUpdateMultiRows(t *testing.T, genUpdate genSQLFunc) { "`c2`=CASE WHEN `c` = ? AND `c2` = ? THEN ? WHEN `c` = ? AND `c2` = ? THEN ? END, " + "`c3`=CASE WHEN `c` = ? AND `c2` = ? THEN ? WHEN `c` = ? AND `c2` = ? THEN ? END " + "WHERE (`c` = ? AND `c2` = ?) OR (`c` = ? AND `c2` = ?)" - expectedArgs := []interface{}{ + expectedArgs := []any{ 1, 2, 10, 4, 5, 40, 1, 2, 20, 4, 5, 50, 1, 2, 30, 4, 5, 60, @@ -100,8 +100,8 @@ func testGenUpdateMultiRowsOneColPK(t *testing.T, genUpdate genSQLFunc) { sourceTI2 := mockTableInfo(t, "CREATE TABLE tb2 (c INT, c2 INT, c3 INT, PRIMARY KEY (c))") targetTI := mockTableInfo(t, "CREATE TABLE tb (c INT, c2 INT, c3 INT, PRIMARY KEY (c))") - change1 := NewRowChange(source1, target, []interface{}{1, 2, 3}, []interface{}{10, 20, 30}, sourceTI1, targetTI, nil) - change2 := NewRowChange(source2, target, []interface{}{4, 5, 6}, []interface{}{40, 50, 60}, sourceTI2, targetTI, nil) + change1 := NewRowChange(source1, target, []any{1, 2, 3}, []any{10, 20, 30}, sourceTI1, targetTI, nil) + change2 := NewRowChange(source2, target, []any{4, 5, 6}, []any{40, 50, 60}, sourceTI2, targetTI, nil) sql, args := genUpdate(change1, change2) expectedSQL := "UPDATE `db`.`tb` SET " + @@ -109,7 +109,7 @@ func testGenUpdateMultiRowsOneColPK(t *testing.T, genUpdate genSQLFunc) { "`c2`=CASE WHEN `c` = ? THEN ? WHEN `c` = ? THEN ? END, " + "`c3`=CASE WHEN `c` = ? THEN ? WHEN `c` = ? THEN ? END " + "WHERE (`c` = ?) OR (`c` = ?)" - expectedArgs := []interface{}{ + expectedArgs := []any{ 1, 10, 4, 40, 1, 20, 4, 50, 1, 30, 4, 60, @@ -127,9 +127,9 @@ func testGenUpdateMultiRowsWithVirtualGeneratedColumn(t *testing.T, genUpdate ge sourceTI := mockTableInfo(t, "CREATE TABLE tb1 (c INT, c1 int as (c+100) virtual not null, c2 INT, c3 INT, PRIMARY KEY (c))") targetTI := mockTableInfo(t, "CREATE TABLE tb (c INT, c1 int as (c+100) virtual not null, c2 INT, c3 INT, PRIMARY KEY (c))") - change1 := NewRowChange(source, target, []interface{}{1, 101, 2, 3}, []interface{}{10, 110, 20, 30}, sourceTI, targetTI, nil) - change2 := NewRowChange(source, target, []interface{}{4, 104, 5, 6}, []interface{}{40, 140, 50, 60}, sourceTI, targetTI, nil) - change3 := NewRowChange(source, target, []interface{}{7, 107, 8, 9}, []interface{}{70, 170, 80, 90}, sourceTI, targetTI, nil) + change1 := NewRowChange(source, target, []any{1, 101, 2, 3}, []any{10, 110, 20, 30}, sourceTI, targetTI, nil) + change2 := NewRowChange(source, target, []any{4, 104, 5, 6}, []any{40, 140, 50, 60}, sourceTI, targetTI, nil) + change3 := NewRowChange(source, target, []any{7, 107, 8, 9}, []any{70, 170, 80, 90}, sourceTI, targetTI, nil) sql, args := genUpdate(change1, change2, change3) expectedSQL := "UPDATE `db`.`tb` SET " + @@ -137,7 +137,7 @@ func testGenUpdateMultiRowsWithVirtualGeneratedColumn(t *testing.T, genUpdate ge "`c2`=CASE WHEN `c` = ? THEN ? WHEN `c` = ? THEN ? WHEN `c` = ? THEN ? END, " + "`c3`=CASE WHEN `c` = ? THEN ? WHEN `c` = ? THEN ? WHEN `c` = ? THEN ? END " + "WHERE (`c` = ?) OR (`c` = ?) OR (`c` = ?)" - expectedArgs := []interface{}{ + expectedArgs := []any{ 1, 10, 4, 40, 7, 70, 1, 20, 4, 50, 7, 80, 1, 30, 4, 60, 7, 90, @@ -158,9 +158,9 @@ func testGenUpdateMultiRowsWithVirtualGeneratedColumns(t *testing.T, genUpdate g targetTI := mockTableInfo(t, `CREATE TABLE tb (c0 int as (c4*c4) virtual not null, c1 int as (c+100) virtual not null, c2 INT, c3 INT, c4 INT, PRIMARY KEY (c4))`) - change1 := NewRowChange(source, target, []interface{}{1, 101, 2, 3, 1}, []interface{}{100, 110, 20, 30, 10}, sourceTI, targetTI, nil) - change2 := NewRowChange(source, target, []interface{}{16, 104, 5, 6, 4}, []interface{}{1600, 140, 50, 60, 40}, sourceTI, targetTI, nil) - change3 := NewRowChange(source, target, []interface{}{49, 107, 8, 9, 7}, []interface{}{4900, 170, 80, 90, 70}, sourceTI, targetTI, nil) + change1 := NewRowChange(source, target, []any{1, 101, 2, 3, 1}, []any{100, 110, 20, 30, 10}, sourceTI, targetTI, nil) + change2 := NewRowChange(source, target, []any{16, 104, 5, 6, 4}, []any{1600, 140, 50, 60, 40}, sourceTI, targetTI, nil) + change3 := NewRowChange(source, target, []any{49, 107, 8, 9, 7}, []any{4900, 170, 80, 90, 70}, sourceTI, targetTI, nil) sql, args := genUpdate(change1, change2, change3) expectedSQL := "UPDATE `db`.`tb` SET " + @@ -168,7 +168,7 @@ func testGenUpdateMultiRowsWithVirtualGeneratedColumns(t *testing.T, genUpdate g "`c3`=CASE WHEN `c4` = ? THEN ? WHEN `c4` = ? THEN ? WHEN `c4` = ? THEN ? END, " + "`c4`=CASE WHEN `c4` = ? THEN ? WHEN `c4` = ? THEN ? WHEN `c4` = ? THEN ? END " + "WHERE (`c4` = ?) OR (`c4` = ?) OR (`c4` = ?)" - expectedArgs := []interface{}{ + expectedArgs := []any{ 1, 20, 4, 50, 7, 80, 1, 30, 4, 60, 7, 90, 1, 10, 4, 40, 7, 70, @@ -186,9 +186,9 @@ func testGenUpdateMultiRowsWithStoredGeneratedColumn(t *testing.T, genUpdate gen sourceTI := mockTableInfo(t, "CREATE TABLE tb1 (c INT, c1 int as (c+100) stored, c2 INT, c3 INT, PRIMARY KEY (c1))") targetTI := mockTableInfo(t, "CREATE TABLE tb (c INT, c1 int as (c+100) stored, c2 INT, c3 INT, PRIMARY KEY (c1))") - change1 := NewRowChange(source, target, []interface{}{1, 101, 2, 3}, []interface{}{10, 110, 20, 30}, sourceTI, targetTI, nil) - change2 := NewRowChange(source, target, []interface{}{4, 104, 5, 6}, []interface{}{40, 140, 50, 60}, sourceTI, targetTI, nil) - change3 := NewRowChange(source, target, []interface{}{7, 107, 8, 9}, []interface{}{70, 170, 80, 90}, sourceTI, targetTI, nil) + change1 := NewRowChange(source, target, []any{1, 101, 2, 3}, []any{10, 110, 20, 30}, sourceTI, targetTI, nil) + change2 := NewRowChange(source, target, []any{4, 104, 5, 6}, []any{40, 140, 50, 60}, sourceTI, targetTI, nil) + change3 := NewRowChange(source, target, []any{7, 107, 8, 9}, []any{70, 170, 80, 90}, sourceTI, targetTI, nil) sql, args := genUpdate(change1, change2, change3) expectedSQL := "UPDATE `db`.`tb` SET " + @@ -196,7 +196,7 @@ func testGenUpdateMultiRowsWithStoredGeneratedColumn(t *testing.T, genUpdate gen "`c2`=CASE WHEN `c1` = ? THEN ? WHEN `c1` = ? THEN ? WHEN `c1` = ? THEN ? END, " + "`c3`=CASE WHEN `c1` = ? THEN ? WHEN `c1` = ? THEN ? WHEN `c1` = ? THEN ? END " + "WHERE (`c1` = ?) OR (`c1` = ?) OR (`c1` = ?)" - expectedArgs := []interface{}{ + expectedArgs := []any{ 101, 10, 104, 40, 107, 70, 101, 20, 104, 50, 107, 80, 101, 30, 104, 60, 107, 90, @@ -218,18 +218,18 @@ func TestGenInsertMultiRows(t *testing.T) { sourceTI2 := mockTableInfo(t, "CREATE TABLE tb2 (gen INT AS (c+1), c INT PRIMARY KEY, c2 INT)") targetTI := mockTableInfo(t, "CREATE TABLE tb (gen INT AS (c+1), c INT PRIMARY KEY, c2 INT)") - change1 := NewRowChange(source1, target, nil, []interface{}{2, 1, 2}, sourceTI1, targetTI, nil) - change2 := NewRowChange(source2, target, nil, []interface{}{4, 3, 4}, sourceTI2, targetTI, nil) + change1 := NewRowChange(source1, target, nil, []any{2, 1, 2}, sourceTI1, targetTI, nil) + change2 := NewRowChange(source2, target, nil, []any{4, 3, 4}, sourceTI2, targetTI, nil) sql, args := GenInsertSQL(DMLInsert, change1, change2) require.Equal(t, "INSERT INTO `db`.`tb` (`c`,`c2`) VALUES (?,?),(?,?)", sql) - require.Equal(t, []interface{}{1, 2, 3, 4}, args) + require.Equal(t, []any{1, 2, 3, 4}, args) sql, args = GenInsertSQL(DMLReplace, change1, change2) require.Equal(t, "REPLACE INTO `db`.`tb` (`c`,`c2`) VALUES (?,?),(?,?)", sql) - require.Equal(t, []interface{}{1, 2, 3, 4}, args) + require.Equal(t, []any{1, 2, 3, 4}, args) sql, args = GenInsertSQL(DMLInsertOnDuplicateUpdate, change1, change2) require.Equal(t, "INSERT INTO `db`.`tb` (`c`,`c2`) VALUES (?,?),(?,?) ON DUPLICATE KEY UPDATE `c`=VALUES(`c`),`c2`=VALUES(`c2`)", sql) - require.Equal(t, []interface{}{1, 2, 3, 4}, args) + require.Equal(t, []any{1, 2, 3, 4}, args) } diff --git a/pkg/sqlmodel/reduce.go b/pkg/sqlmodel/reduce.go index f7cc25221f..be14958a19 100644 --- a/pkg/sqlmodel/reduce.go +++ b/pkg/sqlmodel/reduce.go @@ -33,7 +33,7 @@ func (r *RowChange) HasNotNullUniqueIdx() bool { // changes of one row. // We always use same index for same table structure to get IdentityValues. // two groups returned are from preValues and postValues. -func (r *RowChange) IdentityValues() ([]interface{}, []interface{}) { +func (r *RowChange) IdentityValues() ([]any, []any) { r.lazyInitWhereHandle() indexInfo := r.whereHandle.UniqueNotNullIdx @@ -49,7 +49,7 @@ func (r *RowChange) IdentityValues() ([]interface{}, []interface{}) { // make sure it's not updating the identity itself. // we extract identity from preValues for update/delete, postValues for insert. // if there's no primary key, return all values. -func (r *RowChange) RowIdentity() []interface{} { +func (r *RowChange) RowIdentity() []any { r.lazyInitWhereHandle() targetVals := r.preValues @@ -62,7 +62,7 @@ func (r *RowChange) RowIdentity() []interface{} { return targetVals } - identityVals := make([]interface{}, 0, len(indexInfo.Columns)) + identityVals := make([]any, 0, len(indexInfo.Columns)) for _, column := range indexInfo.Columns { identityVals = append(identityVals, targetVals[column.Offset]) } @@ -106,7 +106,7 @@ func (r *RowChange) IsPrimaryOrUniqueKeyUpdated() bool { } r.lazyInitWhereHandle() - identityUpdated := func(pre, post []interface{}) bool { + identityUpdated := func(pre, post []any) bool { if len(pre) != len(post) { // should not happen return true @@ -144,9 +144,9 @@ func (r *RowChange) IsPrimaryOrUniqueKeyUpdated() bool { } // identityValuesByIndex extra pre and post column values of given index -func (r *RowChange) identityValuesByIndex(indexInfo *timodel.IndexInfo) ([]interface{}, []interface{}) { - pre := make([]interface{}, 0, len(indexInfo.Columns)) - post := make([]interface{}, 0, len(indexInfo.Columns)) +func (r *RowChange) identityValuesByIndex(indexInfo *timodel.IndexInfo) ([]any, []any) { + pre := make([]any, 0, len(indexInfo.Columns)) + post := make([]any, 0, len(indexInfo.Columns)) for _, column := range indexInfo.Columns { if r.preValues != nil { @@ -160,7 +160,7 @@ func (r *RowChange) identityValuesByIndex(indexInfo *timodel.IndexInfo) ([]inter } // genKey gens key by values e.g. "a.1.b". -func genKey(values []interface{}) string { +func genKey(values []any) string { builder := new(strings.Builder) for i, v := range values { if i != 0 { diff --git a/pkg/sqlmodel/reduce_test.go b/pkg/sqlmodel/reduce_test.go index 85f4086ec1..3cafaa62da 100644 --- a/pkg/sqlmodel/reduce_test.go +++ b/pkg/sqlmodel/reduce_test.go @@ -26,22 +26,22 @@ func TestIdentity(t *testing.T) { source := &cdcmodel.TableName{Schema: "db", Table: "tb1"} sourceTI1 := mockTableInfo(t, "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT)") - change := NewRowChange(source, nil, []interface{}{1, 2}, nil, sourceTI1, nil, nil) + change := NewRowChange(source, nil, []any{1, 2}, nil, sourceTI1, nil, nil) pre, post := change.IdentityValues() - require.Equal(t, []interface{}{1}, pre) + require.Equal(t, []any{1}, pre) require.Len(t, post, 0) - change = NewRowChange(source, nil, []interface{}{1, 2}, []interface{}{1, 4}, sourceTI1, nil, nil) + change = NewRowChange(source, nil, []any{1, 2}, []any{1, 4}, sourceTI1, nil, nil) pre, post = change.IdentityValues() - require.Equal(t, []interface{}{1}, pre) - require.Equal(t, []interface{}{1}, post) + require.Equal(t, []any{1}, pre) + require.Equal(t, []any{1}, post) require.False(t, change.IsIdentityUpdated()) sourceTI2 := mockTableInfo(t, "CREATE TABLE tb1 (c INT, c2 INT)") - change = NewRowChange(source, nil, nil, []interface{}{5, 6}, sourceTI2, nil, nil) + change = NewRowChange(source, nil, nil, []any{5, 6}, sourceTI2, nil, nil) pre, post = change.IdentityValues() require.Len(t, pre, 0) - require.Equal(t, []interface{}{5, 6}, post) + require.Equal(t, []any{5, 6}, post) } func TestIdentityUpdatedWithUniqueKeys(t *testing.T) { @@ -50,23 +50,23 @@ func TestIdentityUpdatedWithUniqueKeys(t *testing.T) { source := &cdcmodel.TableName{Schema: "db", Table: "tb1"} sourceTI := mockTableInfo(t, "CREATE TABLE tb1 (id INT PRIMARY KEY, uk1 INT UNIQUE NOT NULL, uk2 INT UNIQUE, val INT)") - change := NewRowChange(source, nil, []interface{}{1, 10, 100, 7}, []interface{}{1, 10, 100, 9}, sourceTI, nil, nil) + change := NewRowChange(source, nil, []any{1, 10, 100, 7}, []any{1, 10, 100, 9}, sourceTI, nil, nil) require.False(t, change.IsIdentityUpdated()) require.False(t, change.IsPrimaryOrUniqueKeyUpdated()) - change = NewRowChange(source, nil, []interface{}{1, 10, 100, 7}, []interface{}{2, 10, 100, 7}, sourceTI, nil, nil) + change = NewRowChange(source, nil, []any{1, 10, 100, 7}, []any{2, 10, 100, 7}, sourceTI, nil, nil) require.True(t, change.IsIdentityUpdated()) require.True(t, change.IsPrimaryOrUniqueKeyUpdated()) - change = NewRowChange(source, nil, []interface{}{2, 10, 100, 7}, []interface{}{2, 20, 100, 7}, sourceTI, nil, nil) + change = NewRowChange(source, nil, []any{2, 10, 100, 7}, []any{2, 20, 100, 7}, sourceTI, nil, nil) require.False(t, change.IsIdentityUpdated()) require.True(t, change.IsPrimaryOrUniqueKeyUpdated()) - change = NewRowChange(source, nil, []interface{}{2, 20, 100, 7}, []interface{}{2, 20, 200, 7}, sourceTI, nil, nil) + change = NewRowChange(source, nil, []any{2, 20, 100, 7}, []any{2, 20, 200, 7}, sourceTI, nil, nil) require.False(t, change.IsIdentityUpdated()) require.True(t, change.IsPrimaryOrUniqueKeyUpdated()) - change = NewRowChange(source, nil, []interface{}{2, 20, nil, 7}, []interface{}{2, 20, 200, 7}, sourceTI, nil, nil) + change = NewRowChange(source, nil, []any{2, 20, nil, 7}, []any{2, 20, 200, 7}, sourceTI, nil, nil) require.False(t, change.IsIdentityUpdated()) require.True(t, change.IsPrimaryOrUniqueKeyUpdated()) } @@ -77,7 +77,7 @@ func TestSplit(t *testing.T) { source := &cdcmodel.TableName{Schema: "db", Table: "tb1"} sourceTI1 := mockTableInfo(t, "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT)") - change := NewRowChange(source, nil, []interface{}{1, 2}, []interface{}{3, 4}, sourceTI1, nil, nil) + change := NewRowChange(source, nil, []any{1, 2}, []any{3, 4}, sourceTI1, nil, nil) require.True(t, change.IsIdentityUpdated()) del, ins := change.SplitUpdate() delIDKey := del.IdentityKey() @@ -92,47 +92,47 @@ func (s *dpanicSuite) TestReduce() { sourceTI := mockTableInfo(s.T(), "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT)") cases := []struct { - pre1 []interface{} - post1 []interface{} - pre2 []interface{} - post2 []interface{} - preAfter []interface{} - postAfter []interface{} + pre1 []any + post1 []any + pre2 []any + post2 []any + preAfter []any + postAfter []any }{ // INSERT + UPDATE { nil, - []interface{}{1, 2}, - []interface{}{1, 2}, - []interface{}{3, 4}, + []any{1, 2}, + []any{1, 2}, + []any{3, 4}, nil, - []interface{}{3, 4}, + []any{3, 4}, }, // INSERT + DELETE { nil, - []interface{}{1, 2}, - []interface{}{1, 2}, + []any{1, 2}, + []any{1, 2}, nil, - []interface{}{1, 2}, + []any{1, 2}, nil, }, // UPDATE + UPDATE { - []interface{}{1, 2}, - []interface{}{1, 3}, - []interface{}{1, 3}, - []interface{}{1, 4}, - []interface{}{1, 2}, - []interface{}{1, 4}, + []any{1, 2}, + []any{1, 3}, + []any{1, 3}, + []any{1, 4}, + []any{1, 2}, + []any{1, 4}, }, // UPDATE + DELETE { - []interface{}{1, 2}, - []interface{}{1, 3}, - []interface{}{1, 3}, + []any{1, 2}, + []any{1, 3}, + []any{1, 3}, nil, - []interface{}{1, 2}, + []any{1, 2}, nil, }, } @@ -148,8 +148,8 @@ func (s *dpanicSuite) TestReduce() { } // test reduce on IdentityUpdated will DPanic - change1 := NewRowChange(source, nil, []interface{}{1, 2}, []interface{}{3, 4}, sourceTI, nil, nil) - change2 := NewRowChange(source, nil, []interface{}{3, 4}, []interface{}{5, 6}, sourceTI, nil, nil) + change1 := NewRowChange(source, nil, []any{1, 2}, []any{3, 4}, sourceTI, nil, nil) + change2 := NewRowChange(source, nil, []any{3, 4}, []any{5, 6}, sourceTI, nil, nil) s.Panics(func() { change2.Reduce(change1) }) diff --git a/pkg/sqlmodel/row_change.go b/pkg/sqlmodel/row_change.go index 700a8617d4..b4a458c128 100644 --- a/pkg/sqlmodel/row_change.go +++ b/pkg/sqlmodel/row_change.go @@ -61,8 +61,8 @@ type RowChange struct { // Optional source table name used only by CausalityKeys. causalityKeySourceTable *cdcmodel.TableName - preValues []interface{} - postValues []interface{} + preValues []any + postValues []any sourceTableInfo *timodel.TableInfo targetTableInfo *timodel.TableInfo @@ -92,8 +92,8 @@ type RowChange struct { func NewRowChange( sourceTable *cdcmodel.TableName, targetTable *cdcmodel.TableName, - preValues []interface{}, - postValues []interface{}, + preValues []any, + postValues []any, sourceTableInfo *timodel.TableInfo, downstreamTableInfo *timodel.TableInfo, tiCtx sessionctx.Context, @@ -241,7 +241,7 @@ func (r *RowChange) lazyInitWhereHandle() { // whereColumnsAndValues returns columns and values to identify the row, to form // the WHERE clause. -func (r *RowChange) whereColumnsAndValues() ([]string, []interface{}) { +func (r *RowChange) whereColumnsAndValues() ([]string, []any) { r.lazyInitWhereHandle() columns, values := r.sourceTableInfo.Columns, r.preValues @@ -271,7 +271,7 @@ func (r *RowChange) whereColumnsAndValues() ([]string, []interface{}) { // genWhere generates WHERE clause for UPDATE and DELETE to identify the row. // the SQL part is written to `buf` and the args part is returned. -func (r *RowChange) genWhere(buf *strings.Builder) []interface{} { +func (r *RowChange) genWhere(buf *strings.Builder) []any { whereColumns, whereValues := r.whereColumnsAndValues() for i, col := range whereColumns { @@ -288,7 +288,7 @@ func (r *RowChange) genWhere(buf *strings.Builder) []interface{} { return whereValues } -func (r *RowChange) genDeleteSQL() (string, []interface{}) { +func (r *RowChange) genDeleteSQL() (string, []any) { if r.tp != RowChangeDelete && r.tp != RowChangeUpdate { log.L().DPanic("illegal type for genDeleteSQL", zap.String("sourceTable", r.sourceTable.String()), @@ -307,7 +307,7 @@ func (r *RowChange) genDeleteSQL() (string, []interface{}) { return buf.String(), whereArgs } -func (r *RowChange) genUpdateSQL() (string, []interface{}) { +func (r *RowChange) genUpdateSQL() (string, []any) { if r.tp != RowChangeUpdate { log.L().DPanic("illegal type for genUpdateSQL", zap.String("sourceTable", r.sourceTable.String()), @@ -323,7 +323,7 @@ func (r *RowChange) genUpdateSQL() (string, []interface{}) { // Build target generated columns lower names set to accelerate following check generatedColumns := generatedColumnsNameSet(r.targetTableInfo.Columns) - args := make([]interface{}, 0, len(r.preValues)+len(r.postValues)) + args := make([]any, 0, len(r.preValues)+len(r.postValues)) writtenFirstCol := false for i, col := range r.sourceTableInfo.Columns { if _, ok := generatedColumns[col.Name.L]; ok { @@ -346,7 +346,7 @@ func (r *RowChange) genUpdateSQL() (string, []interface{}) { return buf.String(), args } -func (r *RowChange) genInsertSQL(tp DMLType) (string, []interface{}) { +func (r *RowChange) genInsertSQL(tp DMLType) (string, []any) { return GenInsertSQL(tp, r) } @@ -382,7 +382,7 @@ func (t DMLType) String() string { } // GenSQL generated a DML SQL for this RowChange. -func (r *RowChange) GenSQL(tp DMLType) (string, []interface{}) { +func (r *RowChange) GenSQL(tp DMLType) (string, []any) { switch tp { case DMLInsert, DMLReplace, DMLInsertOnDuplicateUpdate: return r.genInsertSQL(tp) @@ -398,19 +398,19 @@ func (r *RowChange) GenSQL(tp DMLType) (string, []interface{}) { } // GetPreValues is only used in tests. -func (r *RowChange) GetPreValues() []interface{} { +func (r *RowChange) GetPreValues() []any { return r.preValues } // GetPostValues is only used in tests. -func (r *RowChange) GetPostValues() []interface{} { +func (r *RowChange) GetPostValues() []any { return r.postValues } // RowValues returns the values of this row change // for INSERT and UPDATE, it is the post values. // for DELETE, it is the pre values. -func (r *RowChange) RowValues() []interface{} { +func (r *RowChange) RowValues() []any { switch r.tp { case RowChangeInsert, RowChangeUpdate: return r.postValues diff --git a/pkg/sqlmodel/row_change_test.go b/pkg/sqlmodel/row_change_test.go index a87e10dcd3..d09720bb95 100644 --- a/pkg/sqlmodel/row_change_test.go +++ b/pkg/sqlmodel/row_change_test.go @@ -68,8 +68,8 @@ func TestNewRowChange(t *testing.T) { expected := &RowChange{ sourceTable: source, targetTable: target, - preValues: []interface{}{1, 2}, - postValues: []interface{}{1, 3}, + preValues: []any{1, 2}, + postValues: []any{1, 3}, sourceTableInfo: sourceTI, targetTableInfo: targetTI, tiSessionCtx: tiSession, @@ -77,7 +77,7 @@ func TestNewRowChange(t *testing.T) { whereHandle: nil, } - actual := NewRowChange(source, target, []interface{}{1, 2}, []interface{}{1, 3}, sourceTI, targetTI, tiSession) + actual := NewRowChange(source, target, []any{1, 2}, []any{1, 3}, sourceTI, targetTI, tiSession) require.Equal(t, expected, actual) actual.lazyInitWhereHandle() @@ -89,18 +89,18 @@ func TestNewRowChange(t *testing.T) { expected.targetTableInfo = expected.sourceTableInfo expected.tiSessionCtx = utils.ZeroSessionCtx expected.whereHandle = nil - actual = NewRowChange(source, nil, []interface{}{1, 2}, []interface{}{1, 3}, sourceTI, nil, nil) + actual = NewRowChange(source, nil, []any{1, 2}, []any{1, 3}, sourceTI, nil, nil) require.Equal(t, expected, actual) } func (s *dpanicSuite) TestRowChangeType() { - change := &RowChange{preValues: []interface{}{1}} + change := &RowChange{preValues: []any{1}} change.calculateType() s.Equal(RowChangeDelete, change.tp) - change = &RowChange{preValues: []interface{}{1}, postValues: []interface{}{2}} + change = &RowChange{preValues: []any{1}, postValues: []any{2}} change.calculateType() s.Equal(RowChangeUpdate, change.tp) - change = &RowChange{postValues: []interface{}{1}} + change = &RowChange{postValues: []any{1}} change.calculateType() s.Equal(RowChangeInsert, change.tp) @@ -117,60 +117,60 @@ func (s *dpanicSuite) TestGenDelete() { cases := []struct { sourceCreateSQL string targetCreateSQL string - preValues []interface{} + preValues []any expectedSQL string - expectedArgs []interface{} + expectedArgs []any }{ { "CREATE TABLE tb1 (id INT PRIMARY KEY, name INT)", "CREATE TABLE tb2 (id INT PRIMARY KEY, name INT, extra VARCHAR(20))", - []interface{}{1, 2}, + []any{1, 2}, "DELETE FROM `db`.`tb2` WHERE `id` = ? LIMIT 1", - []interface{}{1}, + []any{1}, }, { "CREATE TABLE tb1 (c INT, c2 INT UNIQUE)", "CREATE TABLE tb2 (c INT, c2 INT UNIQUE)", - []interface{}{1, 2}, + []any{1, 2}, "DELETE FROM `db`.`tb2` WHERE `c2` = ? LIMIT 1", - []interface{}{2}, + []any{2}, }, // next 2 cases test NULL value { "CREATE TABLE tb1 (c INT, c2 INT UNIQUE)", "CREATE TABLE tb2 (c INT, c2 INT UNIQUE)", - []interface{}{1, nil}, + []any{1, nil}, "DELETE FROM `db`.`tb2` WHERE `c` = ? AND `c2` IS ? LIMIT 1", - []interface{}{1, nil}, + []any{1, nil}, }, { "CREATE TABLE tb1 (c INT, c2 INT)", "CREATE TABLE tb2 (c INT, c2 INT)", - []interface{}{1, nil}, + []any{1, nil}, "DELETE FROM `db`.`tb2` WHERE `c` = ? AND `c2` IS ? LIMIT 1", - []interface{}{1, nil}, + []any{1, nil}, }, // next 2 cases test using downstream table to generate WHERE { "CREATE TABLE tb1 (id INT PRIMARY KEY, user_id INT NOT NULL UNIQUE)", "CREATE TABLE tb2 (new_id INT PRIMARY KEY, id INT, user_id INT NOT NULL UNIQUE)", - []interface{}{1, 2}, + []any{1, 2}, "DELETE FROM `db`.`tb2` WHERE `user_id` = ? LIMIT 1", - []interface{}{2}, + []any{2}, }, { "CREATE TABLE tb1 (id INT PRIMARY KEY, c2 INT)", "CREATE TABLE tb2 (new_id INT PRIMARY KEY, id INT, c2 INT)", - []interface{}{1, 2}, + []any{1, 2}, "DELETE FROM `db`.`tb2` WHERE `id` = ? AND `c2` = ? LIMIT 1", - []interface{}{1, 2}, + []any{1, 2}, }, } @@ -185,12 +185,12 @@ func (s *dpanicSuite) TestGenDelete() { // a RowChangeUpdate can still generate DELETE SQL sourceTI := mockTableInfo(s.T(), "CREATE TABLE tb1 (id INT PRIMARY KEY, name INT)") - change := NewRowChange(source, nil, []interface{}{1, 2}, []interface{}{3, 4}, sourceTI, nil, nil) + change := NewRowChange(source, nil, []any{1, 2}, []any{3, 4}, sourceTI, nil, nil) sql, args := change.GenSQL(DMLDelete) s.Equal("DELETE FROM `db`.`tb1` WHERE `id` = ? LIMIT 1", sql) - s.Equal([]interface{}{1}, args) + s.Equal([]any{1}, args) - change = NewRowChange(source, nil, nil, []interface{}{3, 4}, sourceTI, nil, nil) + change = NewRowChange(source, nil, nil, []any{3, 4}, sourceTI, nil, nil) s.Panics(func() { change.GenSQL(DMLDelete) }) @@ -203,57 +203,57 @@ func (s *dpanicSuite) TestGenUpdate() { cases := []struct { sourceCreateSQL string targetCreateSQL string - preValues []interface{} - postValues []interface{} + preValues []any + postValues []any expectedSQL string - expectedArgs []interface{} + expectedArgs []any }{ { "CREATE TABLE tb1 (id INT PRIMARY KEY, name INT)", "CREATE TABLE tb2 (id INT PRIMARY KEY, name INT, extra VARCHAR(20))", - []interface{}{1, 2}, - []interface{}{3, 4}, + []any{1, 2}, + []any{3, 4}, "UPDATE `db`.`tb2` SET `id` = ?, `name` = ? WHERE `id` = ? LIMIT 1", - []interface{}{3, 4, 1}, + []any{3, 4, 1}, }, { "CREATE TABLE tb1 (id INT UNIQUE, name INT)", "CREATE TABLE tb2 (id INT UNIQUE, name INT)", - []interface{}{nil, 2}, - []interface{}{3, 4}, + []any{nil, 2}, + []any{3, 4}, "UPDATE `db`.`tb2` SET `id` = ?, `name` = ? WHERE `id` IS ? AND `name` = ? LIMIT 1", - []interface{}{3, 4, nil, 2}, + []any{3, 4, nil, 2}, }, { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT)", "CREATE TABLE tb2 (c INT, c2 INT)", - []interface{}{1, 2}, - []interface{}{3, 4}, + []any{1, 2}, + []any{3, 4}, "UPDATE `db`.`tb2` SET `c` = ?, `c2` = ? WHERE `c` = ? AND `c2` = ? LIMIT 1", - []interface{}{3, 4, 1, 2}, + []any{3, 4, 1, 2}, }, // next 2 cases test generated column { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT AS (c+1))", "CREATE TABLE tb2 (c INT PRIMARY KEY, c2 INT AS (c+1))", - []interface{}{1, 2}, - []interface{}{3, 4}, + []any{1, 2}, + []any{3, 4}, "UPDATE `db`.`tb2` SET `c` = ? WHERE `c` = ? LIMIT 1", - []interface{}{3, 1}, + []any{3, 1}, }, { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT AS (c+1))", "CREATE TABLE tb2 (c INT PRIMARY KEY, c2 INT)", - []interface{}{1, 2}, - []interface{}{3, 4}, + []any{1, 2}, + []any{3, 4}, "UPDATE `db`.`tb2` SET `c` = ?, `c2` = ? WHERE `c` = ? LIMIT 1", - []interface{}{3, 4, 1}, + []any{3, 4, 1}, }, } @@ -267,7 +267,7 @@ func (s *dpanicSuite) TestGenUpdate() { } sourceTI := mockTableInfo(s.T(), "CREATE TABLE tb1 (id INT PRIMARY KEY, name INT)") - change := NewRowChange(source, nil, nil, []interface{}{3, 4}, sourceTI, nil, nil) + change := NewRowChange(source, nil, nil, []any{3, 4}, sourceTI, nil, nil) s.Panics(func() { change.GenSQL(DMLUpdate) }) @@ -281,24 +281,24 @@ func (s *dpanicSuite) TestExpressionIndex() { UNIQUE KEY j_index ((cast(json_extract(j,'$[*]') as signed array)), id) )` ti := mockTableInfo(s.T(), sql) - change := NewRowChange(source, nil, nil, []interface{}{1, `[1,2,3]`}, ti, nil, nil) + change := NewRowChange(source, nil, nil, []any{1, `[1,2,3]`}, ti, nil, nil) sql, args := change.GenSQL(DMLInsert) s.Equal("INSERT INTO `db`.`tb1` (`id`,`j`) VALUES (?,?)", sql) - s.Equal([]interface{}{1, `[1,2,3]`}, args) + s.Equal([]any{1, `[1,2,3]`}, args) require.Equal(s.T(), 2, change.ColumnCount()) keys := change.CausalityKeys() // TODO: need change it after future fix require.Equal(s.T(), []string{"1.id.db.tb1"}, keys) - change2 := NewRowChange(source, nil, []interface{}{1, `[1,2,3]`}, []interface{}{1, `[1,2,3,4]`}, ti, nil, nil) + change2 := NewRowChange(source, nil, []any{1, `[1,2,3]`}, []any{1, `[1,2,3,4]`}, ti, nil, nil) sql, args = change2.GenSQL(DMLUpdate) s.Equal("UPDATE `db`.`tb1` SET `id` = ?, `j` = ? WHERE `id` = ? LIMIT 1", sql) - s.Equal([]interface{}{1, `[1,2,3,4]`, 1}, args) + s.Equal([]any{1, `[1,2,3,4]`, 1}, args) change2.Reduce(change) sql, args = change2.GenSQL(DMLInsert) s.Equal("INSERT INTO `db`.`tb1` (`id`,`j`) VALUES (?,?)", sql) - s.Equal([]interface{}{1, `[1,2,3,4]`}, args) + s.Equal([]any{1, `[1,2,3,4]`}, args) } func TestGenInsert(t *testing.T) { @@ -310,43 +310,43 @@ func TestGenInsert(t *testing.T) { cases := []struct { sourceCreateSQL string targetCreateSQL string - postValues []interface{} + postValues []any expectedInsertSQL string expectedReplaceSQL string expectedInsertOnDupSQL string - expectedArgs []interface{} + expectedArgs []any }{ { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT)", "CREATE TABLE tb2 (c INT PRIMARY KEY, c2 INT, extra VARCHAR(20))", - []interface{}{1, 2}, + []any{1, 2}, "INSERT INTO `db`.`tb2` (`c`,`c2`) VALUES (?,?)", "REPLACE INTO `db`.`tb2` (`c`,`c2`) VALUES (?,?)", "INSERT INTO `db`.`tb2` (`c`,`c2`) VALUES (?,?) ON DUPLICATE KEY UPDATE `c`=VALUES(`c`),`c2`=VALUES(`c2`)", - []interface{}{1, 2}, + []any{1, 2}, }, // next 2 cases test generated column { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT AS (c+1))", "CREATE TABLE tb2 (c INT PRIMARY KEY, c2 INT AS (c+1))", - []interface{}{1, 2}, + []any{1, 2}, "INSERT INTO `db`.`tb2` (`c`) VALUES (?)", "REPLACE INTO `db`.`tb2` (`c`) VALUES (?)", "INSERT INTO `db`.`tb2` (`c`) VALUES (?) ON DUPLICATE KEY UPDATE `c`=VALUES(`c`)", - []interface{}{1}, + []any{1}, }, { "CREATE TABLE tb1 (c INT PRIMARY KEY, c2 INT AS (c+1))", "CREATE TABLE tb2 (c INT PRIMARY KEY, c2 INT)", - []interface{}{1, 2}, + []any{1, 2}, "INSERT INTO `db`.`tb2` (`c`,`c2`) VALUES (?,?)", "REPLACE INTO `db`.`tb2` (`c`,`c2`) VALUES (?,?)", "INSERT INTO `db`.`tb2` (`c`,`c2`) VALUES (?,?) ON DUPLICATE KEY UPDATE `c`=VALUES(`c`),`c2`=VALUES(`c2`)", - []interface{}{1, 2}, + []any{1, 2}, }, } diff --git a/pkg/sqlmodel/utils.go b/pkg/sqlmodel/utils.go index 75a69cdc9f..eb04d45082 100644 --- a/pkg/sqlmodel/utils.go +++ b/pkg/sqlmodel/utils.go @@ -23,10 +23,10 @@ import ( func getColsAndValuesOfIdx( columns []*timodel.ColumnInfo, indexColumns *timodel.IndexInfo, - data []interface{}, -) ([]*timodel.ColumnInfo, []interface{}) { + data []any, +) ([]*timodel.ColumnInfo, []any) { cols := make([]*timodel.ColumnInfo, 0, len(indexColumns.Columns)) - values := make([]interface{}, 0, len(indexColumns.Columns)) + values := make([]any, 0, len(indexColumns.Columns)) for _, col := range indexColumns.Columns { cols = append(cols, columns[col.Offset]) values = append(values, data[col.Offset]) @@ -40,7 +40,7 @@ func valuesHolder(n int) string { var builder strings.Builder builder.Grow((n-1)*2 + 3) builder.WriteByte('(') - for i := 0; i < n; i++ { + for i := range n { if i > 0 { builder.WriteString(",") } @@ -62,7 +62,7 @@ func generatedColumnsNameSet(columns []*timodel.ColumnInfo) map[string]struct{} } // ColValAsStr convert column value as string -func ColValAsStr(v interface{}) string { +func ColValAsStr(v any) string { switch dv := v.(type) { case []byte: return string(dv) diff --git a/pkg/sqlmodel/where_handle.go b/pkg/sqlmodel/where_handle.go index 740524f52a..be0e2a44d3 100644 --- a/pkg/sqlmodel/where_handle.go +++ b/pkg/sqlmodel/where_handle.go @@ -130,7 +130,7 @@ func allColsNotNull(idx *model.IndexInfo, cols []*model.ColumnInfo) bool { // - an UNIQUE index whose columns are all NOT NULL, or // - an UNIQUE index and the data are all NOT NULL. // For the last case, last used index is swapped to front. -func (h *WhereHandle) getWhereIdxByData(data []interface{}) *model.IndexInfo { +func (h *WhereHandle) getWhereIdxByData(data []any) *model.IndexInfo { if h == nil { log.L().DPanic("WhereHandle is nil") return nil diff --git a/pkg/sqlmodel/where_handle_test.go b/pkg/sqlmodel/where_handle_test.go index bf1f57d409..4972a0ea75 100644 --- a/pkg/sqlmodel/where_handle_test.go +++ b/pkg/sqlmodel/where_handle_test.go @@ -202,16 +202,16 @@ CREATE TABLE t ( require.NoError(t, err) handle := GetWhereHandle(ti, ti) - idx := handle.getWhereIdxByData([]interface{}{nil, 2, 3, 4}) + idx := handle.getWhereIdxByData([]any{nil, 2, 3, 4}) require.Equal(t, "idx2", idx.Name.L) require.Equal(t, idx, handle.UniqueIdxs[0]) // last used index is moved to front - idx = handle.getWhereIdxByData([]interface{}{1, 2, 3, nil}) + idx = handle.getWhereIdxByData([]any{1, 2, 3, nil}) require.Equal(t, "idx1", idx.Name.L) require.Equal(t, idx, handle.UniqueIdxs[0]) // no index available - idx = handle.getWhereIdxByData([]interface{}{1, nil, 3, nil}) + idx = handle.getWhereIdxByData([]any{1, nil, 3, nil}) require.Nil(t, idx) } diff --git a/pkg/tcpserver/tcp_server_test.go b/pkg/tcpserver/tcp_server_test.go index 5d53a13591..220238e7f5 100644 --- a/pkg/tcpserver/tcp_server_test.go +++ b/pkg/tcpserver/tcp_server_test.go @@ -51,20 +51,16 @@ func TestTCPServerInsecureHTTP1(t *testing.T) { var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx) require.Error(t, err) require.Regexp(t, ".*ErrTCPServerClosed.*", err.Error()) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { testWithHTTPWorkload(ctx, t, server, addr, &security.Credential{}) cancel() - }() + }) wg.Wait() } @@ -88,20 +84,16 @@ func TestTCPServerTLSHTTP1(t *testing.T) { var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx) require.Error(t, err) require.Regexp(t, ".*ErrTCPServerClosed.*", err.Error()) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer cancel() testWithHTTPWorkload(ctx, t, server, addr, makeCredential4Testing(t)) - }() + }) wg.Wait() } @@ -124,20 +116,16 @@ func TestTCPServerInsecureGrpc(t *testing.T) { var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx) require.Error(t, err) require.Regexp(t, ".*ErrTCPServerClosed.*", err.Error()) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { testWithGrpcWorkload(ctx, t, server, addr, &security.Credential{}) cancel() - }() + }) wg.Wait() } @@ -161,20 +149,16 @@ func TestTCPServerTLSGrpc(t *testing.T) { var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx) require.Error(t, err) require.Regexp(t, ".*ErrTCPServerClosed.*", err.Error()) - }() + }) - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { testWithGrpcWorkload(ctx, t, server, addr, makeCredential4Testing(t)) cancel() - }() + }) wg.Wait() } @@ -236,9 +220,7 @@ func testWithHTTPWorkload(_ context.Context, t *testing.T, server TCPServer, add var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := httpServer.Serve(server.HTTP1Listener()) if err != nil && err != http.ErrServerClosed { require.FailNow(t, @@ -246,7 +228,7 @@ func testWithHTTPWorkload(_ context.Context, t *testing.T, server TCPServer, add "%d", err.Error()) } - }() + }) scheme := "http" if credentials.IsTLSEnabled() { @@ -281,12 +263,10 @@ func testWithGrpcWorkload(ctx context.Context, t *testing.T, server TCPServer, a var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := grpcServer.Serve(server.GrpcListener()) require.NoError(t, err) - }() + }) var conn *grpc.ClientConn if credentials.IsTLSEnabled() { @@ -305,7 +285,7 @@ func testWithGrpcWorkload(ctx context.Context, t *testing.T, server TCPServer, a client := grpcTestingProto.NewTestServiceClient(conn) - for i := 0; i < 5; i++ { + for i := range 5 { result, err := client.Ping(ctx, &grpcTestingProto.PingRequest{ Value: fmt.Sprintf("%d", i), }) @@ -313,15 +293,13 @@ func testWithGrpcWorkload(ctx context.Context, t *testing.T, server TCPServer, a require.Equal(t, fmt.Sprintf("%d", i), result.Value) } - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { defer grpcServer.GracefulStop() stream, err := client.PingStream(ctx) require.NoError(t, err) - for i := 0; i < 10; i++ { + for i := range 10 { err := stream.Send(&grpcTestingProto.PingRequest{ Value: fmt.Sprintf("%d", i), }) @@ -331,7 +309,7 @@ func testWithGrpcWorkload(ctx context.Context, t *testing.T, server TCPServer, a require.NoError(t, err) require.Equal(t, fmt.Sprintf("%d", i), received.Value) } - }() + }) wg.Wait() } @@ -348,13 +326,11 @@ func TestTcpServerClose(t *testing.T) { require.NoError(t, err) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := server.Run(ctx) require.Error(t, err) require.Regexp(t, ".*ErrTCPServerClosed.*", err.Error()) - }() + }) httpServer := &http.Server{} http.HandleFunc("/", func(writer http.ResponseWriter, _ *http.Request) { @@ -366,13 +342,11 @@ func TestTcpServerClose(t *testing.T) { http.DefaultServeMux = http.NewServeMux() }() - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { err := httpServer.Serve(server.HTTP1Listener()) require.Error(t, err) require.Regexp(t, ".*mux: server closed.*", err.Error()) - }() + }) cli, err := httputil.NewClient(&security.Credential{}) require.NoError(t, err) @@ -386,7 +360,7 @@ func TestTcpServerClose(t *testing.T) { require.Equal(t, 200, resp.StatusCode) // Close should be idempotent. - for i := 0; i < 3; i++ { + for range 3 { err := server.Close() require.NoError(t, err) } diff --git a/pkg/upstream/manager.go b/pkg/upstream/manager.go index 93c9bf7f57..459377c380 100644 --- a/pkg/upstream/manager.go +++ b/pkg/upstream/manager.go @@ -187,7 +187,7 @@ func (m *Manager) Get(upstreamID uint64) (*Upstream, bool) { // Please make sure it will only be called once when capture exits. func (m *Manager) Close() { m.cancel() - m.ups.Range(func(k, v interface{}) bool { + m.ups.Range(func(k, v any) bool { v.(*Upstream).Close() m.ups.Delete(k) return true @@ -197,7 +197,7 @@ func (m *Manager) Close() { // Visit on each upstream, return error on the first func (m *Manager) Visit(visitor func(up *Upstream) error) error { var err error - m.ups.Range(func(k, v interface{}) bool { + m.ups.Range(func(k, v any) bool { err = visitor(v.(*Upstream)) return err == nil }) @@ -224,7 +224,7 @@ func (m *Manager) Tick(ctx context.Context, defer m.mu.Unlock() var err error - m.ups.Range(func(k, v interface{}) bool { + m.ups.Range(func(k, v any) bool { select { case <-ctx.Done(): err = ctx.Err() diff --git a/pkg/upstream/upstream.go b/pkg/upstream/upstream.go index d169c78126..74817c21d9 100644 --- a/pkg/upstream/upstream.go +++ b/pkg/upstream/upstream.go @@ -222,11 +222,9 @@ func initUpstream(ctx context.Context, up *Upstream, cfg CaptureTopologyCfg) err return errors.Trace(err) } - up.wg.Add(1) - go func() { - defer up.wg.Done() + up.wg.Go(func() { up.PDClock.Run(ctx) - }() + }) log.Info("upstream initialize successfully", zap.Uint64("upstreamID", up.ID)) atomic.StoreInt32(&up.status, normal) diff --git a/pkg/upstream/upstream_test.go b/pkg/upstream/upstream_test.go index ebcf9728fc..1004a38dd1 100644 --- a/pkg/upstream/upstream_test.go +++ b/pkg/upstream/upstream_test.go @@ -14,7 +14,6 @@ package upstream import ( - "context" "fmt" "strconv" "sync" @@ -90,8 +89,7 @@ func TestTrySetIdleTime(t *testing.T) { func TestRegisterTopo(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() clientURL, etcdServer, err := etcd.SetupEmbedEtcd(t.TempDir()) defer etcdServer.Close() @@ -144,8 +142,7 @@ func TestRegisterTopo(t *testing.T) { func TestVerify(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() clientURL, etcdServer, err := etcd.SetupEmbedEtcd(t.TempDir()) defer etcdServer.Close() diff --git a/pkg/util/atomic_test.go b/pkg/util/atomic_test.go index 900720ebb5..777ec5adf0 100644 --- a/pkg/util/atomic_test.go +++ b/pkg/util/atomic_test.go @@ -57,10 +57,8 @@ func TestMustCompareAndIncrease(t *testing.T) { doIncrease() }() - wg.Add(1) // Test target never decrease. - go func() { - defer wg.Done() + wg.Go(func() { for { select { case <-ctx.Done(): @@ -71,7 +69,7 @@ func TestMustCompareAndIncrease(t *testing.T) { require.Greater(t, target.Load(), v) } } - }() + }) cancel() wg.Wait() diff --git a/pkg/util/json_writer.go b/pkg/util/json_writer.go index c30f997753..d3678bc917 100644 --- a/pkg/util/json_writer.go +++ b/pkg/util/json_writer.go @@ -27,7 +27,7 @@ var jsonAPI = jsoniter.Config{ }.Froze() var jWriterPool = sync.Pool{ - New: func() interface{} { + New: func() any { return &JSONWriter{} }, } diff --git a/pkg/util/seahash/seahash_test.go b/pkg/util/seahash/seahash_test.go index f4c6a78dfd..47acd460d2 100644 --- a/pkg/util/seahash/seahash_test.go +++ b/pkg/util/seahash/seahash_test.go @@ -33,7 +33,7 @@ func ExampleSum64() { func TestRandom(t *testing.T) { expected := "d30e85ff891306b8" str := []byte("abcdegfhijklmnabcdegfhijklmnabcdegfhijklmn") - for i := 0; i < 1000; i++ { + for i := range 1000 { r := rand.NewSource(int64(i)) s := str h := New() diff --git a/pkg/util/test_helper_test.go b/pkg/util/test_helper_test.go index 75169afe32..20bd6250fd 100644 --- a/pkg/util/test_helper_test.go +++ b/pkg/util/test_helper_test.go @@ -55,7 +55,7 @@ func TestHandleErr(t *testing.T) { count int32 ) errg := HandleErrWithErrGroup(ctx, errCh, func(e error) { atomic.AddInt32(&count, 1) }) - for i := 0; i < 5; i++ { + for range 5 { errCh <- errors.New("test error") } require.True(t, WaitSomething(5, time.Millisecond*10, func() bool { return atomic.LoadInt32(&count) == int32(5) })) diff --git a/pkg/uuid/uuid_test.go b/pkg/uuid/uuid_test.go index 2cb4672b2d..dd1e5057f3 100644 --- a/pkg/uuid/uuid_test.go +++ b/pkg/uuid/uuid_test.go @@ -47,7 +47,7 @@ func TestConstGenerator(t *testing.T) { uid := "const-uuid" gen := NewConstGenerator(uid) - for i := 0; i < 3; i++ { + for range 3 { require.Equal(t, uid, gen.NewString()) } } diff --git a/pkg/version/check_test.go b/pkg/version/check_test.go index 66fbdf4a33..2d0ed95771 100644 --- a/pkg/version/check_test.go +++ b/pkg/version/check_test.go @@ -54,7 +54,7 @@ func (m *mockPDClient) ServeHTTP(resp http.ResponseWriter, _ *http.Request) { } if m.getPDVersion != nil { - _, _ = resp.Write([]byte(fmt.Sprintf(`{"version":"%s"}`, m.getPDVersion()))) + _, _ = resp.Write(fmt.Appendf(nil, `{"version":"%s"}`, m.getPDVersion())) } } @@ -74,7 +74,7 @@ func TestCheckClusterVersion(t *testing.T) { defer srv.Close() cli, err := httputil.NewClient(nil) require.Nil(t, err) - for i := 0; i < 20; i++ { + for i := range 20 { time.Sleep(100 * time.Millisecond) resp, err := cli.Get(context.Background(), pdAddr) if err == nil { diff --git a/pkg/workerpool/async_pool_test.go b/pkg/workerpool/async_pool_test.go index 68ca2c015d..c4c2ce6dd3 100644 --- a/pkg/workerpool/async_pool_test.go +++ b/pkg/workerpool/async_pool_test.go @@ -40,7 +40,7 @@ func TestBasic(t *testing.T) { var sum int32 var wg sync.WaitGroup - for i := 0; i < 100; i++ { + for i := range 100 { wg.Add(1) finalI := i err := pool.Go(ctx, func() { @@ -70,7 +70,7 @@ func TestEventuallyRun(t *testing.T) { pool := newDefaultAsyncPoolImpl(4) errg.Go(func() error { defer cancelLoop() - for i := 0; i < 10; i++ { + for range 10 { log.Info("running pool") err := runForDuration(ctx, time.Millisecond*500, func(ctx context.Context) error { return pool.Run(ctx) diff --git a/pkg/workerpool/pool.go b/pkg/workerpool/pool.go index 8558c2c70a..3ba8c63d7e 100644 --- a/pkg/workerpool/pool.go +++ b/pkg/workerpool/pool.go @@ -24,7 +24,7 @@ type WorkerPool interface { // RegisterEvent returns a handle that can be used to trigger the execution of `f`. // `f` will be called with a context that is a child of the context with which Run is called. // TODO more reasonable usage of contexts, potentially involving context merging. - RegisterEvent(f func(ctx context.Context, event interface{}) error) EventHandle + RegisterEvent(f func(ctx context.Context, event any) error) EventHandle // Run runs the WorkerPool. // Internally several Goroutines are spawned. @@ -39,10 +39,10 @@ type EventHandle interface { // Note: events are always processed in the order they are added. // Unregistering the EventHandle MAY CAUSE EVENT LOSSES. But for an event lost, any event after it is guaranteed to be lost too. // Cancelling `ctx` here will cancel the on-going or next execution of the event. - AddEvent(ctx context.Context, event interface{}) error + AddEvent(ctx context.Context, event any) error // AddEvents is like AddEvent but retrieves a slice instead of an object. - AddEvents(ctx context.Context, events []interface{}) error + AddEvents(ctx context.Context, events []any) error // SetTimer is used to provide a function that is periodic called, as long as the EventHandle has not been unregistered. // The current implementation uses as the base clock source a ticker whose interval is the const workerPoolDefaultClockSourceInterval. diff --git a/pkg/workerpool/pool_impl.go b/pkg/workerpool/pool_impl.go index 0a10addebb..7a75644159 100644 --- a/pkg/workerpool/pool_impl.go +++ b/pkg/workerpool/pool_impl.go @@ -49,7 +49,7 @@ func NewDefaultWorkerPool(numWorkers int) WorkerPool { func newDefaultPoolImpl(hasher Hasher, numWorkers int) *defaultPoolImpl { workers := make([]*worker, numWorkers) - for i := 0; i < numWorkers; i++ { + for i := range numWorkers { workers[i] = newWorker() } return &defaultPoolImpl{ @@ -75,7 +75,7 @@ func (p *defaultPoolImpl) Run(ctx context.Context) error { return errg.Wait() } -func (p *defaultPoolImpl) RegisterEvent(f func(ctx context.Context, event interface{}) error) EventHandle { +func (p *defaultPoolImpl) RegisterEvent(f func(ctx context.Context, event any) error) EventHandle { handler := &defaultEventHandle{ f: f, errCh: make(chan error, 1), @@ -99,7 +99,7 @@ const ( type defaultEventHandle struct { // the function to be run each time the event is triggered - f func(ctx context.Context, event interface{}) error + f func(ctx context.Context, event any) error // must be accessed atomically status handleStatus // channel for the error returned by f @@ -126,7 +126,7 @@ type defaultEventHandle struct { errorHandler func(err error) } -func (h *defaultEventHandle) AddEvent(ctx context.Context, event interface{}) error { +func (h *defaultEventHandle) AddEvent(ctx context.Context, event any) error { status := atomic.LoadInt32(&h.status) if status != handleRunning { return cerrors.ErrWorkerPoolHandleCancelled.GenWithStackByArgs() @@ -149,7 +149,7 @@ func (h *defaultEventHandle) AddEvent(ctx context.Context, event interface{}) er return nil } -func (h *defaultEventHandle) AddEvents(ctx context.Context, events []interface{}) error { +func (h *defaultEventHandle) AddEvents(ctx context.Context, events []any) error { status := atomic.LoadInt32(&h.status) if status != handleRunning { return cerrors.ErrWorkerPoolHandleCancelled.GenWithStackByArgs() diff --git a/pkg/workerpool/pool_test.go b/pkg/workerpool/pool_test.go index 5a0480dd15..2537921889 100644 --- a/pkg/workerpool/pool_test.go +++ b/pkg/workerpool/pool_test.go @@ -39,7 +39,7 @@ func TestTaskError(t *testing.T) { return pool.Run(ctx) }) - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { if event.(int) == 3 { return errors.New("test error") } @@ -49,16 +49,14 @@ func TestTaskError(t *testing.T) { }) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - for i := 0; i < 10; i++ { + wg.Go(func() { + for i := range 10 { err := handle.AddEvent(ctx, i) if err != nil { require.Regexp(t, ".*ErrWorkerPoolHandleCancelled.*", err) } } - }() + }) select { case <-ctx.Done(): @@ -86,7 +84,7 @@ func TestTimerError(t *testing.T) { }) counter := 0 - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { return nil }).SetTimer(ctx, time.Millisecond*200, func(ctx context.Context) error { if counter == 3 { @@ -117,7 +115,7 @@ func TestMultiError(t *testing.T) { return pool.Run(ctx) }) - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { if event.(int) >= 3 { return errors.New("test error") } @@ -125,16 +123,14 @@ func TestMultiError(t *testing.T) { }) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - for i := 0; i < 10; i++ { + wg.Go(func() { + for i := range 10 { err := handle.AddEvent(ctx, i) if err != nil { require.Regexp(t, ".*ErrWorkerPoolHandleCancelled.*", err) } } - }() + }) select { case <-ctx.Done(): @@ -162,7 +158,7 @@ func TestCancelHandle(t *testing.T) { }) var num int32 - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { atomic.StoreInt32(&num, int32(event.(int))) return nil }) @@ -234,7 +230,7 @@ func TestCancelTimer(t *testing.T) { _ = failpoint.Disable("github.com/pingcap/tiflow/pkg/workerpool/unregisterDelayPoint") }() - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { return nil }).SetTimer(ctx, 200*time.Millisecond, func(ctx context.Context) error { return nil @@ -270,7 +266,7 @@ func TestErrorAndCancelRace(t *testing.T) { }) var racedVar int - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { return errors.New("fake") }).OnExit(func(err error) { time.Sleep(100 * time.Millisecond) @@ -301,7 +297,7 @@ func TestTimer(t *testing.T) { time.Sleep(200 * time.Millisecond) - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { if event.(int) == 3 { return errors.New("test error") } @@ -343,10 +339,10 @@ func TestBasics(t *testing.T) { var wg sync.WaitGroup wg.Add(16) - for i := 0; i < 16; i++ { + for i := range 16 { finalI := i resultCh := make(chan int, 128) - handler := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handler := pool.RegisterEvent(func(ctx context.Context, event any) error { select { case <-ctx.Done(): return ctx.Err() @@ -357,7 +353,7 @@ func TestBasics(t *testing.T) { }) errg.Go(func() error { - for j := 0; j < 256; j++ { + for j := range 256 { err := handler.AddEvent(ctx, j) if err != nil { return errors.Trace(err) @@ -396,8 +392,7 @@ func TestBasics(t *testing.T) { // TestCancelByAddEventContext makes sure that the event handle can be cancelled by the context used // to call `AddEvent`. func TestCancelByAddEventContext(t *testing.T) { - poolCtx, poolCancel := context.WithCancel(context.Background()) - defer poolCancel() + poolCtx := t.Context() pool := newDefaultPoolImpl(&defaultHasher{}, 4) go func() { err := pool.Run(poolCtx) @@ -408,14 +403,14 @@ func TestCancelByAddEventContext(t *testing.T) { defer cancel() errg, ctx := errgroup.WithContext(ctx) - for i := 0; i < 8; i++ { - handler := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + for range 8 { + handler := pool.RegisterEvent(func(ctx context.Context, event any) error { <-ctx.Done() return ctx.Err() }) errg.Go(func() error { - for j := 0; j < 64; j++ { + for j := range 64 { err := handler.AddEvent(ctx, j) if err != nil { return nil @@ -441,8 +436,7 @@ func TestCancelByAddEventContext(t *testing.T) { } func TestGracefulUnregister(t *testing.T) { - poolCtx, poolCancel := context.WithCancel(context.Background()) - defer poolCancel() + poolCtx := t.Context() pool := newDefaultPoolImpl(&defaultHasher{}, 4) go func() { err := pool.Run(poolCtx) @@ -455,7 +449,7 @@ func TestGracefulUnregister(t *testing.T) { waitCh := make(chan struct{}) var lastEventIdx int64 - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { select { case <-ctx.Done(): return errors.Trace(ctx.Err()) @@ -469,9 +463,7 @@ func TestGracefulUnregister(t *testing.T) { }) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { var maxEventIdx int64 for i := int64(0); ; i++ { err := handle.AddEvent(ctx, i+1) @@ -486,7 +478,7 @@ func TestGracefulUnregister(t *testing.T) { require.Eventually(t, func() (success bool) { return atomic.LoadInt64(&lastEventIdx) == maxEventIdx }, time.Millisecond*500, time.Millisecond*10) - }() + }) time.Sleep(time.Millisecond * 200) go func() { @@ -504,8 +496,7 @@ func TestGracefulUnregister(t *testing.T) { } func TestGracefulUnregisterTimeout(t *testing.T) { - poolCtx, poolCancel := context.WithCancel(context.Background()) - defer poolCancel() + poolCtx := t.Context() pool := newDefaultPoolImpl(&defaultHasher{}, 4) go func() { err := pool.Run(poolCtx) @@ -517,7 +508,7 @@ func TestGracefulUnregisterTimeout(t *testing.T) { waitCh := make(chan struct{}) - handle := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handle := pool.RegisterEvent(func(ctx context.Context, event any) error { select { case <-waitCh: return nil @@ -573,14 +564,13 @@ func TestSynchronizeLog(t *testing.T) { // Benchmark workerpool with ping-pong workflow. // go test -benchmem -run='^$' -bench '^(BenchmarkWorkerpool)$' github.com/pingcap/tiflow/pkg/workerpool func BenchmarkWorkerpool(b *testing.B) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := b.Context() pool := newDefaultPoolImpl(&defaultHasher{}, 4) go func() { _ = pool.Run(ctx) }() ch := make(chan int) - handler := pool.RegisterEvent(func(ctx context.Context, event interface{}) error { + handler := pool.RegisterEvent(func(ctx context.Context, event any) error { ch <- event.(int) return nil }) diff --git a/sync_diff_inspector/checkpoints/checkpoints.go b/sync_diff_inspector/checkpoints/checkpoints.go index 6d68325caf..f4d550dee5 100644 --- a/sync_diff_inspector/checkpoints/checkpoints.go +++ b/sync_diff_inspector/checkpoints/checkpoints.go @@ -225,12 +225,12 @@ func (hp *nodeHeap) Swap(i, j int) { } // Push implementation of push for the heap interface -func (hp *nodeHeap) Push(x interface{}) { +func (hp *nodeHeap) Push(x any) { hp.Nodes = append(hp.Nodes, x.(*Node)) } // Pop implementation of pop for heap interface -func (hp *nodeHeap) Pop() (item interface{}) { +func (hp *nodeHeap) Pop() (item any) { if len(hp.Nodes) == 0 { return } diff --git a/sync_diff_inspector/checkpoints/checkpoints_test.go b/sync_diff_inspector/checkpoints/checkpoints_test.go index 56d5ae761a..e66328cb04 100644 --- a/sync_diff_inspector/checkpoints/checkpoints_test.go +++ b/sync_diff_inspector/checkpoints/checkpoints_test.go @@ -38,7 +38,7 @@ func TestSaveChunk(t *testing.T) { require.Nil(t, id) wg := &sync.WaitGroup{} rounds := 100 - for i := 0; i < rounds; i++ { + for i := range rounds { wg.Add(1) go func(i int) { node := &Node{ @@ -87,7 +87,7 @@ func TestLoadChunk(t *testing.T) { rounds := 100 testColNames := []ast.CIStr{ast.NewCIStr("col1"), ast.NewCIStr("col2")} wg := &sync.WaitGroup{} - for i := 0; i < rounds; i++ { + for i := range rounds { wg.Add(1) go func(i int) { node := &Node{ diff --git a/sync_diff_inspector/chunk/chunk.go b/sync_diff_inspector/chunk/chunk.go index 8fe76dac37..48663abd0d 100644 --- a/sync_diff_inspector/chunk/chunk.go +++ b/sync_diff_inspector/chunk/chunk.go @@ -16,6 +16,7 @@ package chunk import ( "encoding/json" "fmt" + "maps" "strconv" "strings" @@ -468,9 +469,7 @@ func (r *Range) Clone() *Range { newChunk.Type = r.Type newChunk.Where = r.Where newChunk.Args = r.Args - for i, v := range r.columnOffset { - newChunk.columnOffset[i] = v - } + maps.Copy(newChunk.columnOffset, r.columnOffset) newChunk.Index = r.Index.Copy() newChunk.IsFirst = r.IsFirst newChunk.IsLast = r.IsLast diff --git a/sync_diff_inspector/diff/diff.go b/sync_diff_inspector/diff/diff.go index 5927aea420..03576ac2cc 100644 --- a/sync_diff_inspector/diff/diff.go +++ b/sync_diff_inspector/diff/diff.go @@ -618,11 +618,9 @@ func (df *Diff) binSearch(ctx context.Context, targetSource source.Source, table func (df *Diff) compareChecksumAndGetCount(ctx context.Context, tableRange *splitter.RangeInfo) (bool, int64, int64, error) { var wg sync.WaitGroup var upstreamInfo, downstreamInfo *source.ChecksumInfo - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { upstreamInfo = df.upstream.GetCountAndMD5(ctx, tableRange) - }() + }) downstreamInfo = df.downstream.GetCountAndMD5(ctx, tableRange) wg.Wait() diff --git a/sync_diff_inspector/report/report.go b/sync_diff_inspector/report/report.go index bdd27c029c..081142ea9c 100644 --- a/sync_diff_inspector/report/report.go +++ b/sync_diff_inspector/report/report.go @@ -18,6 +18,7 @@ import ( "database/sql" "fmt" "io" + "maps" "os" "path/filepath" "sort" @@ -101,9 +102,7 @@ func (r *Report) LoadReport(reportInfo *Report) { if _, ok := r.TableResults[schema]; !ok { r.TableResults[schema] = make(map[string]*TableResult) } - for table, result := range tableMap { - r.TableResults[schema][table] = result - } + maps.Copy(r.TableResults[schema], tableMap) } r.refreshResult() } diff --git a/sync_diff_inspector/report/report_test.go b/sync_diff_inspector/report/report_test.go index e12ab74a3d..402a64ed0a 100644 --- a/sync_diff_inspector/report/report_test.go +++ b/sync_diff_inspector/report/report_test.go @@ -97,7 +97,7 @@ func TestReport(t *testing.T) { } configsBytes := make([][]byte, 3) - for i := 0; i < 3; i++ { + for i := range 3 { buf := new(bytes.Buffer) err := toml.NewEncoder(buf).Encode(configs[i]) require.NoError(t, err) @@ -199,7 +199,7 @@ func TestCalculateTotal(t *testing.T) { } configsBytes := make([][]byte, 3) - for i := 0; i < 3; i++ { + for i := range 3 { buf := new(bytes.Buffer) err := toml.NewEncoder(buf).Encode(configs[i]) require.NoError(t, err) @@ -252,7 +252,7 @@ func TestPrint(t *testing.T) { } configsBytes := make([][]byte, 3) - for i := 0; i < 3; i++ { + for i := range 3 { buf := new(bytes.Buffer) err := toml.NewEncoder(buf).Encode(configs[i]) require.NoError(t, err) @@ -328,7 +328,7 @@ func TestGetSnapshot(t *testing.T) { } configsBytes := make([][]byte, 3) - for i := 0; i < 3; i++ { + for i := range 3 { buf := new(bytes.Buffer) err := toml.NewEncoder(buf).Encode(configs[i]) require.NoError(t, err) @@ -462,7 +462,7 @@ func TestCommitSummary(t *testing.T) { } configsBytes := make([][]byte, 3) - for i := 0; i < 3; i++ { + for i := range 3 { buf := new(bytes.Buffer) err := toml.NewEncoder(buf).Encode(configs[i]) require.NoError(t, err) diff --git a/sync_diff_inspector/source/common/common_test.go b/sync_diff_inspector/source/common/common_test.go index f6db790278..d22e6e1a9a 100644 --- a/sync_diff_inspector/source/common/common_test.go +++ b/sync_diff_inspector/source/common/common_test.go @@ -57,7 +57,7 @@ func TestRowData(t *testing.T) { }) } - for i := 0; i < len(ids); i++ { + for i := range ids { rowData := heap.Pop(rowDatas).(RowData) id := string(rowData.Data["id"].Data) name := string(rowData.Data["name"].Data) diff --git a/sync_diff_inspector/source/common/rows.go b/sync_diff_inspector/source/common/rows.go index 892157e46f..c9cc7a7dc6 100644 --- a/sync_diff_inspector/source/common/rows.go +++ b/sync_diff_inspector/source/common/rows.go @@ -104,12 +104,12 @@ func (r RowDatas) Swap(i, j int) { } // Push implements heap.Interface's Push function -func (r *RowDatas) Push(x interface{}) { +func (r *RowDatas) Push(x any) { r.Rows = append(r.Rows, x.(RowData)) } // Pop implements heap.Interface's Pop function -func (r *RowDatas) Pop() (x interface{}) { +func (r *RowDatas) Pop() (x any) { if len(r.Rows) == 0 { return nil } diff --git a/sync_diff_inspector/source/source.go b/sync_diff_inspector/source/source.go index c5956ae3c2..73828caf28 100644 --- a/sync_diff_inspector/source/source.go +++ b/sync_diff_inspector/source/source.go @@ -447,7 +447,7 @@ func checkTableMatched(tableDiffs []*common.TableDiff, targetMap map[string]stru func getIndexMapForTable(tableDiffs []*common.TableDiff) map[string]int { tableIndexMap := make(map[string]int) - for i := 0; i < len(tableDiffs); i++ { + for i := range tableDiffs { tableUniqueID := utils.UniqueID(tableDiffs[i].Schema, tableDiffs[i].Table) tableIndexMap[tableUniqueID] = i } diff --git a/sync_diff_inspector/source/source_test.go b/sync_diff_inspector/source/source_test.go index 081c8e4ae9..9e8b0b5c63 100644 --- a/sync_diff_inspector/source/source_test.go +++ b/sync_diff_inspector/source/source_test.go @@ -265,7 +265,7 @@ func TestTiDBSource(t *testing.T) { analyze := tidb.GetTableAnalyzer() statsRows := sqlmock.NewRows([]string{"is_index", "hist_id", "bucket_id", "count", "lower_bound", "upper_bound"}) - for i := 0; i < 5; i++ { + for i := range 5 { statsRows.AddRow(1, 1, i, (i+1)*64, fmt.Sprintf("(%d, %d)", i*64, i*12), fmt.Sprintf("(%d, %d)", (i+1)*64-1, (i+1)*12-1)) } mock.ExpectQuery("SELECT is_index, hist_id, bucket_id, count, lower_bound, upper_bound FROM mysql.stats_buckets WHERE table_id IN \\(\\s*SELECT tidb_table_id FROM information_schema.tables WHERE table_schema = \\? AND table_name = \\? UNION ALL SELECT tidb_partition_id FROM information_schema.partitions WHERE table_schema = \\? AND table_name = \\?\\s*\\) ORDER BY is_index, hist_id, bucket_id"). @@ -293,7 +293,7 @@ func TestFallbackToRandomIfRangeIsSet(t *testing.T) { mock.ExpectQuery("SELECT version()*").WillReturnRows(sqlmock.NewRows([]string{"version()"}).AddRow("5.7.25-TiDB-v4.0.12")) mock.ExpectQuery(regexp.QuoteMeta("SELECT COUNT(1) cnt")).WillReturnRows(sqlmock.NewRows([]string{"cnt"}).AddRow(100)) statsRows := sqlmock.NewRows([]string{"hist_id", "is_index", "bucket_id", "count", "lower_bound", "upper_bound"}) - for i := 0; i < 5; i++ { + for i := range 5 { statsRows.AddRow(1, 1, i, (i+1)*64, fmt.Sprintf("(%d, %d)", i*64, i*12), fmt.Sprintf("(%d, %d)", (i+1)*64-1, (i+1)*12-1)) } f, err := filter.Parse([]string{"source_test.*"}) @@ -390,7 +390,7 @@ func TestMysqlShardSources(t *testing.T) { shard, err := NewMySQLSources(ctx, tableDiffs, cs, 4, f, false) require.NoError(t, err) - for i := 0; i < len(dbs); i++ { + for range dbs { infoRows := sqlmock.NewRows([]string{"Table", "Create Table"}).AddRow("test_t", "CREATE TABLE `source_test`.`test1` (`a` int, `b` varchar(24), `c` float, primary key(`a`, `b`))") variableRows := sqlmock.NewRows([]string{"Variable_name", "Value"}).AddRow("sql_mode", "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION") @@ -404,7 +404,7 @@ func TestMysqlShardSources(t *testing.T) { for n, tableCase := range tableCases { require.Equal(t, n, tableCase.rangeInfo.GetTableIndex()) var resChecksum uint64 = 0 - for i := 0; i < len(dbs); i++ { + for i := range dbs { resChecksum = resChecksum + 1< db -> table - allTablesMap := make(map[string]map[string]interface{}) + allTablesMap := make(map[string]map[string]any) sourceSchemas, err := dbutil.GetSchemas(ctx, ds.Conn) if err != nil { return nil, errors.Annotatef(err, "get schemas from database") diff --git a/sync_diff_inspector/splitter/index_fields.go b/sync_diff_inspector/splitter/index_fields.go index 9c35164aa9..afb71f74f4 100644 --- a/sync_diff_inspector/splitter/index_fields.go +++ b/sync_diff_inspector/splitter/index_fields.go @@ -85,7 +85,7 @@ func (f *indexFields) MatchesIndex(index *model.IndexInfo) bool { // Sort for comparison sortColsInPlace(indexCols) - for i := 0; i < len(indexCols); i++ { + for i := range indexCols { if f.cols[i].ID != indexCols[i].ID { return false } diff --git a/sync_diff_inspector/splitter/limit.go b/sync_diff_inspector/splitter/limit.go index 81bcce6f91..36f3860bf2 100644 --- a/sync_diff_inspector/splitter/limit.go +++ b/sync_diff_inspector/splitter/limit.go @@ -284,7 +284,7 @@ func (lmt *LimitIterator) produceChunks(ctx context.Context, bucketID int) { } } -func (lmt *LimitIterator) getLimitRow(ctx context.Context, query string, args []interface{}) (map[string]*dbutil.ColumnData, error) { +func (lmt *LimitIterator) getLimitRow(ctx context.Context, query string, args []any) (map[string]*dbutil.ColumnData, error) { rows, err := lmt.dbConn.QueryContext(ctx, query, args...) if err != nil { return nil, err diff --git a/sync_diff_inspector/splitter/splitter_test.go b/sync_diff_inspector/splitter/splitter_test.go index ce0888fc32..e2dc786b38 100644 --- a/sync_diff_inspector/splitter/splitter_test.go +++ b/sync_diff_inspector/splitter/splitter_test.go @@ -36,7 +36,7 @@ import ( type chunkResult struct { chunkStr string - args []interface{} + args []any } func TestSplitRangeByRandom(t *testing.T) { @@ -61,13 +61,13 @@ func TestSplitRangeByRandom(t *testing.T) { []chunkResult{ { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"0", "0", "a", "5", "5", "g"}, + []any{"0", "0", "a", "5", "5", "g"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"5", "5", "g", "7", "7", "n"}, + []any{"5", "5", "g", "7", "7", "n"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"7", "7", "n", "10", "10", "z"}, + []any{"7", "7", "n", "10", "10", "z"}, }, }, }, @@ -82,13 +82,13 @@ func TestSplitRangeByRandom(t *testing.T) { []chunkResult{ { "((`b` > ?) OR (`b` = ? AND `a` > ?)) AND ((`b` < ?) OR (`b` = ? AND `a` <= ?))", - []interface{}{"a", "a", "0", "g", "g", "5"}, + []any{"a", "a", "0", "g", "g", "5"}, }, { "((`b` > ?) OR (`b` = ? AND `a` > ?)) AND ((`b` < ?) OR (`b` = ? AND `a` <= ?))", - []interface{}{"g", "g", "5", "n", "n", "7"}, + []any{"g", "g", "5", "n", "n", "7"}, }, { "((`b` > ?) OR (`b` = ? AND `a` > ?)) AND ((`b` < ?) OR (`b` = ? AND `a` <= ?))", - []interface{}{"n", "n", "7", "z", "z", "10"}, + []any{"n", "n", "7", "z", "z", "10"}, }, }, }, @@ -102,13 +102,13 @@ func TestSplitRangeByRandom(t *testing.T) { []chunkResult{ { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"a", "g"}, + []any{"a", "g"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"g", "n"}, + []any{"g", "n"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"n", "z"}, + []any{"n", "z"}, }, }, }, @@ -122,10 +122,10 @@ func TestSplitRangeByRandom(t *testing.T) { []chunkResult{ { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"a", "g"}, + []any{"a", "g"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"g", "z"}, + []any{"g", "z"}, }, }, }, @@ -139,7 +139,7 @@ func TestSplitRangeByRandom(t *testing.T) { []chunkResult{ { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"a", "z"}, + []any{"a", "z"}, }, }, }, @@ -187,22 +187,22 @@ func TestRandomSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"1", "1", "a"}, + []any{"1", "1", "a"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"1", "1", "a", "2", "2", "b"}, + []any{"1", "1", "a", "2", "2", "b"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"2", "2", "b", "3", "3", "c"}, + []any{"2", "2", "b", "3", "3", "c"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"3", "3", "c", "4", "4", "d"}, + []any{"3", "3", "c", "4", "4", "d"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"4", "4", "d", "5", "5", "e"}, + []any{"4", "4", "d", "5", "5", "e"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"5", "5", "e"}, + []any{"5", "5", "e"}, }, }, }, { @@ -216,22 +216,22 @@ func TestRandomSpliter(t *testing.T) { []chunkResult{ { "(`b` <= ?)", - []interface{}{"a"}, + []any{"a"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"a", "b"}, + []any{"a", "b"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"b", "c"}, + []any{"b", "c"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"c", "d"}, + []any{"c", "d"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"d", "e"}, + []any{"d", "e"}, }, { "(`b` > ?)", - []interface{}{"e"}, + []any{"e"}, }, }, }, { @@ -246,22 +246,22 @@ func TestRandomSpliter(t *testing.T) { []chunkResult{ { "(`b` < ?) OR (`b` = ? AND `c` <= ?)", - []interface{}{"a", "a", "1.1"}, + []any{"a", "a", "1.1"}, }, { "((`b` > ?) OR (`b` = ? AND `c` > ?)) AND ((`b` < ?) OR (`b` = ? AND `c` <= ?))", - []interface{}{"a", "a", "1.1", "b", "b", "2.2"}, + []any{"a", "a", "1.1", "b", "b", "2.2"}, }, { "((`b` > ?) OR (`b` = ? AND `c` > ?)) AND ((`b` < ?) OR (`b` = ? AND `c` <= ?))", - []interface{}{"b", "b", "2.2", "c", "c", "3.3"}, + []any{"b", "b", "2.2", "c", "c", "3.3"}, }, { "((`b` > ?) OR (`b` = ? AND `c` > ?)) AND ((`b` < ?) OR (`b` = ? AND `c` <= ?))", - []interface{}{"c", "c", "3.3", "d", "d", "4.4"}, + []any{"c", "c", "3.3", "d", "d", "4.4"}, }, { "((`b` > ?) OR (`b` = ? AND `c` > ?)) AND ((`b` < ?) OR (`b` = ? AND `c` <= ?))", - []interface{}{"d", "d", "4.4", "e", "e", "5.5"}, + []any{"d", "d", "4.4", "e", "e", "5.5"}, }, { "(`b` > ?) OR (`b` = ? AND `c` > ?)", - []interface{}{"e", "e", "5.5"}, + []any{"e", "e", "5.5"}, }, }, }, { @@ -275,22 +275,22 @@ func TestRandomSpliter(t *testing.T) { []chunkResult{ { "(`b` <= ?)", - []interface{}{"a"}, + []any{"a"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"a", "b"}, + []any{"a", "b"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"b", "c"}, + []any{"b", "c"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"c", "d"}, + []any{"c", "d"}, }, { "((`b` > ?)) AND ((`b` <= ?))", - []interface{}{"d", "e"}, + []any{"d", "e"}, }, { "(`b` > ?)", - []interface{}{"e"}, + []any{"e"}, }, }, }, { @@ -304,22 +304,22 @@ func TestRandomSpliter(t *testing.T) { []chunkResult{ { "(`a` <= ?)", - []interface{}{"1"}, + []any{"1"}, }, { "((`a` > ?)) AND ((`a` <= ?))", - []interface{}{"1", "2"}, + []any{"1", "2"}, }, { "((`a` > ?)) AND ((`a` <= ?))", - []interface{}{"2", "3"}, + []any{"2", "3"}, }, { "((`a` > ?)) AND ((`a` <= ?))", - []interface{}{"3", "4"}, + []any{"3", "4"}, }, { "((`a` > ?)) AND ((`a` <= ?))", - []interface{}{"4", "5"}, + []any{"4", "5"}, }, { "(`a` > ?)", - []interface{}{"5"}, + []any{"5"}, }, }, }, @@ -379,7 +379,7 @@ func TestRandomSpliter(t *testing.T) { require.NoError(t, err) var chunk *chunk.Range - for j := 0; j < stopJ; j++ { + for range stopJ { chunk, err = iter.Next() require.NoError(t, err) } @@ -415,13 +415,13 @@ func createFakeResultForRandomSplit(t *testing.T, mock sqlmock.Sqlmock, count in // generate fake result for get random value for column a columns := []string{"a", "b", "c", "d", "e", "f"} rowsNames := make([]string, 0, len(randomValues)) - for i := 0; i < len(randomValues); i++ { + for i := range randomValues { rowsNames = append(rowsNames, columns[i]) } randomRows := sqlmock.NewRows(rowsNames) for i := 0; i < len(randomValues[0]); i++ { row := make([]driver.Value, 0, len(randomValues)) - for j := 0; j < len(randomValues); j++ { + for j := range randomValues { row = append(row, randomValues[j][i]) } randomRows.AddRow(row...) @@ -440,49 +440,49 @@ func TestBucketSpliter(t *testing.T) { testCases := []struct { chunkSize int64 - aRandomValues []interface{} - bRandomValues []interface{} + aRandomValues []any + bRandomValues []any expectResult []chunkResult }{ { // chunk size less than the count of bucket 64, and the bucket's count 64 >= 32, so will split by random in every bucket 32, - []interface{}{32, 32 * 3, 32 * 5, 32 * 7, 32 * 9}, - []interface{}{6, 6 * 3, 6 * 5, 6 * 7, 6 * 9}, + []any{32, 32 * 3, 32 * 5, 32 * 7, 32 * 9}, + []any{6, 6 * 3, 6 * 5, 6 * 7, 6 * 9}, []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"32", "32", "6"}, + []any{"32", "32", "6"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"32", "32", "6", "63", "63", "11"}, + []any{"32", "32", "6", "63", "63", "11"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"63", "63", "11", "96", "96", "18"}, + []any{"63", "63", "11", "96", "96", "18"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"96", "96", "18", "127", "127", "23"}, + []any{"96", "96", "18", "127", "127", "23"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"127", "127", "23", "160", "160", "30"}, + []any{"127", "127", "23", "160", "160", "30"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"160", "160", "30", "191", "191", "35"}, + []any{"160", "160", "30", "191", "191", "35"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"191", "191", "35", "224", "224", "42"}, + []any{"191", "191", "35", "224", "224", "42"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"224", "224", "42", "255", "255", "47"}, + []any{"224", "224", "42", "255", "255", "47"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"255", "255", "47", "288", "288", "54"}, + []any{"255", "255", "47", "288", "288", "54"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"288", "288", "54", "319", "319", "59"}, + []any{"288", "288", "54", "319", "319", "59"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"319", "319", "59"}, + []any{"319", "319", "59"}, }, }, }, { @@ -493,22 +493,22 @@ func TestBucketSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"63", "63", "11"}, + []any{"63", "63", "11"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"63", "63", "11", "127", "127", "23"}, + []any{"63", "63", "11", "127", "127", "23"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"127", "127", "23", "191", "191", "35"}, + []any{"127", "127", "23", "191", "191", "35"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"191", "191", "35", "255", "255", "47"}, + []any{"191", "191", "35", "255", "255", "47"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"255", "255", "47", "319", "319", "59"}, + []any{"255", "255", "47", "319", "319", "59"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"319", "319", "59"}, + []any{"319", "319", "59"}, }, }, }, { @@ -519,22 +519,22 @@ func TestBucketSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"63", "63", "11"}, + []any{"63", "63", "11"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"63", "63", "11", "127", "127", "23"}, + []any{"63", "63", "11", "127", "127", "23"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"127", "127", "23", "191", "191", "35"}, + []any{"127", "127", "23", "191", "191", "35"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"191", "191", "35", "255", "255", "47"}, + []any{"191", "191", "35", "255", "255", "47"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"255", "255", "47", "319", "319", "59"}, + []any{"255", "255", "47", "319", "319", "59"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"319", "319", "59"}, + []any{"319", "319", "59"}, }, }, }, { @@ -545,13 +545,13 @@ func TestBucketSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"127", "127", "23"}, + []any{"127", "127", "23"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"127", "127", "23", "255", "255", "47"}, + []any{"127", "127", "23", "255", "255", "47"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"255", "255", "47"}, + []any{"255", "255", "47"}, }, }, }, { @@ -562,13 +562,13 @@ func TestBucketSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"127", "127", "23"}, + []any{"127", "127", "23"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"127", "127", "23", "255", "255", "47"}, + []any{"127", "127", "23", "255", "255", "47"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"255", "255", "47"}, + []any{"255", "255", "47"}, }, }, }, { @@ -579,10 +579,10 @@ func TestBucketSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"191", "191", "35"}, + []any{"191", "191", "35"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"191", "191", "35"}, + []any{"191", "191", "35"}, }, }, }, { @@ -634,10 +634,7 @@ func TestBucketSpliter(t *testing.T) { } sort.Slice(obtainChunks, func(i, j int) bool { - totalIndex := len(obtainChunks[i].args) - if totalIndex > len(obtainChunks[j].args) { - totalIndex = len(obtainChunks[j].args) - } + totalIndex := min(len(obtainChunks[i].args), len(obtainChunks[j].args)) for index := 0; index < totalIndex; index++ { a1, _ := strconv.Atoi(obtainChunks[i].args[index].(string)) a2, _ := strconv.Atoi(obtainChunks[j].args[index].(string)) @@ -718,7 +715,7 @@ func TestBucketSpliter(t *testing.T) { require.Error(t, err) } -func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandomValues []interface{}) { +func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandomValues []any) { /* +---------+------------+-------------+----------+-----------+-------+---------+-------------+-------------+ | Db_name | Table_name | Column_name | Is_index | Bucket_id | Count | Repeats | Lower_Bound | Upper_Bound | @@ -733,7 +730,7 @@ func createFakeResultForBucketSplit(mock sqlmock.Sqlmock, aRandomValues, bRandom // Mock query with subquery to get all table_ids (main table + partitions) at once statsRows := sqlmock.NewRows([]string{"is_index", "hist_id", "bucket_id", "count", "lower_bound", "upper_bound"}) - for i := 0; i < 5; i++ { + for i := range 5 { // Encode index bounds as real encoded keys: PRIMARY(a, b) where both a and b are integers. lowerA, lowerB := i*64, i*12 upperA, upperB := (i+1)*64-1, (i+1)*12-1 @@ -763,8 +760,8 @@ func createFakeResultForCount(t *testing.T, count int) { } } -func createFakeResultForRandom(mock sqlmock.Sqlmock, aRandomValues, bRandomValues []interface{}) { - for i := 0; i < len(aRandomValues); i++ { +func createFakeResultForRandom(mock sqlmock.Sqlmock, aRandomValues, bRandomValues []any) { + for i := range aRandomValues { aRandomRows := sqlmock.NewRows([]string{"a", "b"}) aRandomRows.AddRow(aRandomValues[i], bRandomValues[i]) mock.ExpectQuery("ORDER BY rand_value").WillReturnRows(aRandomRows) @@ -789,19 +786,19 @@ func TestLimitSpliter(t *testing.T) { []chunkResult{ { "(`a` < ?) OR (`a` = ? AND `b` <= ?)", - []interface{}{"1000", "1000", "a"}, + []any{"1000", "1000", "a"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"1000", "1000", "a", "2000", "2000", "b"}, + []any{"1000", "1000", "a", "2000", "2000", "b"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"2000", "2000", "b", "3000", "3000", "c"}, + []any{"2000", "2000", "b", "3000", "3000", "c"}, }, { "((`a` > ?) OR (`a` = ? AND `b` > ?)) AND ((`a` < ?) OR (`a` = ? AND `b` <= ?))", - []interface{}{"3000", "3000", "c", "4000", "4000", "d"}, + []any{"3000", "3000", "c", "4000", "4000", "d"}, }, { "(`a` > ?) OR (`a` = ? AND `b` > ?)", - []interface{}{"4000", "4000", "d"}, + []any{"4000", "4000", "d"}, }, }, }, @@ -899,7 +896,7 @@ func TestRangeInfo(t *testing.T) { rangeInfo.ChunkRange.Index.TableIndex = 1 chunkRange := rangeInfo.GetChunk() require.Equal(t, chunkRange.Where, "((((`a` COLLATE '[23]' > ?)) AND ((`a` COLLATE '[23]' <= ?))) AND ([sdg]))") - require.Equal(t, chunkRange.Args, []interface{}{"1", "2"}) + require.Equal(t, chunkRange.Args, []any{"1", "2"}) require.Equal(t, rangeInfo.GetTableIndex(), 1) @@ -907,7 +904,7 @@ func TestRangeInfo(t *testing.T) { chunkRange = rangeInfo2.GetChunk() require.Equal(t, chunkRange.Where, "((((`a` COLLATE '[23]' > ?)) AND ((`a` COLLATE '[23]' <= ?))) AND ([sdg]))") - require.Equal(t, chunkRange.Args, []interface{}{"1", "2"}) + require.Equal(t, chunkRange.Args, []any{"1", "2"}) require.Equal(t, rangeInfo2.GetTableIndex(), 1) } @@ -1101,7 +1098,7 @@ func createFakeResultForBucketIterator(mock sqlmock.Sqlmock, indexCount int) { statsRows := sqlmock.NewRows([]string{"is_index", "hist_id", "bucket_id", "count", "lower_bound", "upper_bound"}) for i := range []string{"PRIMARY", "i1", "i2", "i3", "i4"} { histID := int64(i + 1) // hist_id starts from 1 - for j := 0; j < 5; j++ { + for j := range 5 { statsRows.AddRow(1, histID, j, (j+1)*64, fmt.Sprintf("(%d, %d)", j*64, j*12), fmt.Sprintf("(%d, %d)", (j+1)*64-1, (j+1)*12-1)) } } diff --git a/sync_diff_inspector/utils/pd.go b/sync_diff_inspector/utils/pd.go index 80587b8f59..3592d68992 100644 --- a/sync_diff_inspector/utils/pd.go +++ b/sync_diff_inspector/utils/pd.go @@ -143,7 +143,7 @@ func GetSpecifiedColumnValueAndClose(rows *sql.Rows, columnName string) ([]strin columnName = strings.ToUpper(columnName) var strs []string columns, _ := rows.Columns() - addr := make([]interface{}, len(columns)) + addr := make([]any, len(columns)) oneRow := make([]sql.NullString, len(columns)) fieldIndex := -1 for i, col := range columns { diff --git a/sync_diff_inspector/utils/utils.go b/sync_diff_inspector/utils/utils.go index dbf769a427..2755390353 100644 --- a/sync_diff_inspector/utils/utils.go +++ b/sync_diff_inspector/utils/utils.go @@ -89,7 +89,7 @@ type taskFunc func() // NewWorkerPool returns a WorkerPool with `limit` workers in the channel. func NewWorkerPool(limit uint, name string) *WorkerPool { workers := make(chan *Worker, limit) - for i := uint(0); i < limit; i++ { + for i := range limit { workers <- &Worker{ID: uint64(i + 1)} } return &WorkerPool{ @@ -103,12 +103,10 @@ func NewWorkerPool(limit uint, name string) *WorkerPool { // Notice: function `Apply` and `WaitFinished` cannot be called in parallel func (pool *WorkerPool) Apply(fn taskFunc) { worker := pool.apply() - pool.wg.Add(1) - go func() { - defer pool.wg.Done() + pool.wg.Go(func() { defer pool.recycle(worker) fn() - }() + }) } // apply waits for an idle worker from the channel and return it @@ -786,8 +784,8 @@ func MinLenInSlices(slices [][]string) int { } // SliceToMap converts Slice to Set -func SliceToMap(slice []string) map[string]interface{} { - sMap := make(map[string]interface{}) +func SliceToMap(slice []string) map[string]any { + sMap := make(map[string]any) for _, str := range slice { sMap[str] = struct{}{} } @@ -795,7 +793,7 @@ func SliceToMap(slice []string) map[string]interface{} { } // GetApproximateMidBySize return the `count`th row in rows that meet the `limitRange`. -func GetApproximateMidBySize(ctx context.Context, db *sql.DB, schema, table string, indexColumns []*model.ColumnInfo, limitRange string, args []interface{}, count int64) (map[string]string, error) { +func GetApproximateMidBySize(ctx context.Context, db *sql.DB, schema, table string, indexColumns []*model.ColumnInfo, limitRange string, args []any, count int64) (map[string]string, error) { /* example mysql> select i_id, i_im_id, i_name from item where i_id > 0 order by i_id, i_im_id, i_name collate limit 5000,1; @@ -824,7 +822,7 @@ func GetApproximateMidBySize(ctx context.Context, db *sql.DB, schema, table stri return nil, errors.Trace(err) } defer rows.Close() - columns := make([]interface{}, len(indexColumns)) + columns := make([]any, len(indexColumns)) for i := range columns { columns[i] = new(string) } @@ -959,7 +957,7 @@ func GetRandomValues( NEXTROW: for rows.Next() { colVals := make([][]byte, len(columns)) - colValsI := make([]interface{}, len(colVals)) + colValsI := make([]any, len(colVals)) for i := range colValsI { colValsI[i] = &colVals[i] } @@ -1079,7 +1077,7 @@ func GetBetterIndex(ctx context.Context, db *sql.DB, schema, table string, table func GetSelectivity(ctx context.Context, db *sql.DB, schemaName, tableName, columnName string, tbInfo *model.TableInfo) (float64, error) { query := fmt.Sprintf("SELECT COUNT(DISTINCT %s)/COUNT(1) as SEL FROM %s;", dbutil.ColumnName(columnName), dbutil.TableName(schemaName, tableName)) var selectivity sql.NullFloat64 - args := []interface{}{} + args := []any{} err := db.QueryRowContext(ctx, query, args...).Scan(&selectivity) if err != nil { log.Warn("execute get selectivity query fail", zap.String("query", query)) diff --git a/sync_diff_inspector/utils/utils_test.go b/sync_diff_inspector/utils/utils_test.go index eb08551403..0a6310c24e 100644 --- a/sync_diff_inspector/utils/utils_test.go +++ b/sync_diff_inspector/utils/utils_test.go @@ -388,7 +388,7 @@ func TestGetTableSize(t *testing.T) { defer conn.Close() dataRows := sqlmock.NewRows([]string{"a", "b"}) rowNums := 1000 - for k := 0; k < rowNums; k++ { + for k := range rowNums { str := fmt.Sprintf("%d", k) dataRows.AddRow(str, str) } diff --git a/tests/integration_tests/api_v2/cases.go b/tests/integration_tests/api_v2/cases.go index 3b040274f9..ea4b9f71fb 100644 --- a/tests/integration_tests/api_v2/cases.go +++ b/tests/integration_tests/api_v2/cases.go @@ -424,7 +424,7 @@ func assertResponseIsOK(resp *Result) { func ensureChangefeed(ctx context.Context, client *CDCRESTClient, id, state string) { var info *ChangeFeedInfo - for i := 0; i < 10; i++ { + for i := range 10 { resp := client.Get(). WithURI("/changefeeds/" + id + "?namespace=test").Do(ctx) if resp.statusCode == 200 { diff --git a/tests/integration_tests/api_v2/model.go b/tests/integration_tests/api_v2/model.go index 3f330ddd95..2aa73788b3 100644 --- a/tests/integration_tests/api_v2/model.go +++ b/tests/integration_tests/api_v2/model.go @@ -141,7 +141,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/tests/integration_tests/api_v2/request.go b/tests/integration_tests/api_v2/request.go index bb8ebdbf2d..64743495fc 100644 --- a/tests/integration_tests/api_v2/request.go +++ b/tests/integration_tests/api_v2/request.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "io" + "maps" "net/http" "net/url" "path" @@ -204,9 +205,7 @@ func (r *Request) WithURI(uri string) *Request { if r.params == nil { r.params = make(url.Values) } - for k, v := range vals { - r.params[k] = v - } + maps.Copy(r.params, vals) } return r } @@ -285,7 +284,7 @@ func (r *Request) WithMaxRetries(maxRetries uint64) *Request { // only supports two types now: // 1. io.Reader // 2. type which can be json marshalled -func (r *Request) WithBody(obj interface{}) *Request { +func (r *Request) WithBody(obj any) *Request { if r.err != nil { return r } @@ -480,7 +479,7 @@ func (r Result) Error() error { } // Into stores the http response body into obj. -func (r Result) Into(obj interface{}) error { +func (r Result) Into(obj any) error { if r.err != nil { return r.err } diff --git a/tests/integration_tests/bank/case.go b/tests/integration_tests/bank/case.go index b13e391510..deeccf4e08 100644 --- a/tests/integration_tests/bank/case.go +++ b/tests/integration_tests/bank/case.go @@ -138,7 +138,7 @@ func (s *sequenceTest) prepare(ctx context.Context, db *sql.DB, accounts, tableI )`, tableID) batchInsertSQLF := func(batchSize, offset int) string { args := make([]string, batchSize) - for j := 0; j < batchSize; j++ { + for j := range batchSize { args[j] = fmt.Sprintf("(%d, 0, 0, 0)", offset+j) } return fmt.Sprintf("INSERT IGNORE INTO accounts_seq%d (id, counter, sequence, startts) VALUES %s", tableID, strings.Join(args, ",")) @@ -254,7 +254,7 @@ func (s *bankTest) prepare(ctx context.Context, db *sql.DB, accounts, tableID, c )`, tableID) batchInsertSQLF := func(batchSize, offset int) string { args := make([]string, batchSize) - for j := 0; j < batchSize; j++ { + for j := range batchSize { args[j] = fmt.Sprintf("(%d, %d, 0)", offset+j, initBalance) } return fmt.Sprintf("INSERT IGNORE INTO accounts%d (id, balance, startts) VALUES %s", tableID, strings.Join(args, ",")) @@ -345,7 +345,7 @@ func prepareImpl( g := new(errgroup.Group) ch := make(chan int, jobCount) - for i := 0; i < concurrency; i++ { + for range concurrency { g.Go(func() error { for { startIndex, ok := <-ch @@ -468,7 +468,7 @@ func run( tests := []testcase{&sequenceTest{}, &bankTest{}} if cleanupOnly { - for tableID := 0; tableID < tables; tableID++ { + for tableID := range tables { for i := range tests { tests[i].cleanup(ctx, upstreamDB, accounts, tableID, true) tests[i].cleanup(ctx, downstreamDB, accounts, tableID, true) @@ -484,7 +484,7 @@ func run( // prepare data for upstream db. for _, test := range tests { - for tableID := 0; tableID < tables; tableID++ { + for tableID := range tables { if err := test.prepare(ctx, upstreamDB, accounts, tableID, concurrency); err != nil { log.Panic("prepare failed", zap.Error(err)) } @@ -510,7 +510,7 @@ func run( valid, tried int64 = 0, 0 ) - for id := 0; id < tables; id++ { + for id := range tables { tableID := id // Workload g.Go(func() error { diff --git a/tests/integration_tests/cdc/dailytest/case.go b/tests/integration_tests/cdc/dailytest/case.go index 3dd44770ad..f14c7b066c 100644 --- a/tests/integration_tests/cdc/dailytest/case.go +++ b/tests/integration_tests/cdc/dailytest/case.go @@ -160,7 +160,7 @@ func RunCase(src *sql.DB, dst *sql.DB, schema string) { // insert 5 * 1M // note limitation of TiDB: https://github.com/pingcap/docs/blob/733a5b0284e70c5b4d22b93a818210a3f6fbb5a0/FAQ.md#the-error-message-transaction-too-large-is-displayed data := make([]byte, 1<<20) - for i := 0; i < 5; i++ { + for i := range 5 { _, err = tx.Query("INSERT INTO binlog_big(id, data) VALUES(?, ?);", i, data) if err != nil { log.S().Fatal(err) @@ -240,27 +240,23 @@ CREATE TABLE growing_cols ( var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { insertSQL := `INSERT INTO growing_cols(id, val) VALUES (?, ?);` mustExec(db, insertSQL, 1, 0) // Keep updating to generate DMLs while the other goroutine's adding columns updateSQL := `UPDATE growing_cols SET val = ? WHERE id = ?;` - for i := 0; i < 256; i++ { + for i := range 256 { mustExec(db, updateSQL, i, 1) } - }() + }) - wg.Add(1) - go func() { - defer wg.Done() - for i := 0; i < 32; i++ { + wg.Go(func() { + for i := range 32 { updateSQL := fmt.Sprintf(`ALTER TABLE growing_cols ADD COLUMN col%d VARCHAR(50);`, i) mustExec(db, updateSQL) } - }() + }) wg.Wait() } @@ -268,7 +264,7 @@ CREATE TABLE growing_cols ( func caseUpdateWhileDroppingCol(db *sql.DB) { const nCols = 10 var builder strings.Builder - for i := 0; i < nCols; i++ { + for i := range nCols { if i != 0 { builder.WriteRune(',') } @@ -283,7 +279,7 @@ CREATE TABLE many_cols ( mustExec(db, createSQL) builder.Reset() - for i := 0; i < nCols; i++ { + for i := range nCols { if i != 0 { builder.WriteRune(',') } @@ -292,7 +288,7 @@ CREATE TABLE many_cols ( cols := builder.String() builder.Reset() - for i := 0; i < nCols; i++ { + for i := range nCols { if i != 0 { builder.WriteRune(',') } @@ -318,7 +314,7 @@ CREATE TABLE many_cols ( } }() - for i := 0; i < nCols; i++ { + for i := range nCols { mustExec(db, fmt.Sprintf("ALTER TABLE many_cols DROP COLUMN col%d;", i)) } close(closeCh) @@ -339,14 +335,14 @@ CREATE TABLE gen_contacts ( insertSQL := "INSERT INTO gen_contacts(first_name, last_name) VALUES(?, ?);" updateSQL := "UPDATE gen_contacts SET other = fullname WHERE first_name = ?" - for i := 0; i < 64; i++ { + for i := range 64 { mustExec(db, insertSQL, fmt.Sprintf("John%d", i), fmt.Sprintf("Dow%d", i)) idxToUpdate := rand.Intn(i + 1) mustExec(db, updateSQL, fmt.Sprintf("John%d", idxToUpdate)) } delSQL := "DELETE FROM gen_contacts WHERE fullname = ?" - for i := 0; i < 10; i++ { + for i := range 10 { mustExec(db, delSQL, fmt.Sprintf("John%d Dow%d", i, i)) } } @@ -366,15 +362,15 @@ AS SELECT user_id, SUM(amount) FROM base_for_view GROUP BY user_id;`) insertSQL := "INSERT INTO base_for_view(user_id, amount) VALUES(?, ?);" updateSQL := "UPDATE base_for_view SET amount = ? WHERE user_id = ?;" deleteSQL := "DELETE FROM base_for_view WHERE user_id = ? AND amount = ?;" - for i := 0; i < 42; i++ { - for j := 0; j < 3; j++ { + for i := range 42 { + for j := range 3 { mustExec(db, insertSQL, i, j*10+i) if i%2 == 0 && j == 1 { mustExec(db, updateSQL, 1111, i) } } } - for i := 0; i < 10; i++ { + for i := range 10 { mustExec(db, deleteSQL, i, 1111) } } @@ -477,7 +473,7 @@ func updatePKUK(db *sql.DB, opNum int) error { return nil } -func mustExec(db *sql.DB, sql string, args ...interface{}) { +func mustExec(db *sql.DB, sql string, args ...any) { _, err := db.Exec(sql, args...) if err != nil { log.S().Fatalf("exec failed, sql: %s args: %v, err: %+v", sql, args, err) diff --git a/tests/integration_tests/cdc/dailytest/db.go b/tests/integration_tests/cdc/dailytest/db.go index 3abd4a0708..e4f1933ff4 100644 --- a/tests/integration_tests/cdc/dailytest/db.go +++ b/tests/integration_tests/cdc/dailytest/db.go @@ -81,14 +81,14 @@ func queryCount(table *table, db *sql.DB) (int, error) { return nums, nil } -func genDeleteSqls(table *table, db *sql.DB, count int) ([]string, [][]interface{}, error) { +func genDeleteSqls(table *table, db *sql.DB, count int) ([]string, [][]any, error) { nums, err := queryCount(table, db) if err != nil { return nil, nil, errors.Trace(err) } var sqls []string - var args [][]interface{} + var args [][]any if nums == 0 || nums-count < 1 { return sqls, args, nil @@ -104,10 +104,10 @@ func genDeleteSqls(table *table, db *sql.DB, count int) ([]string, [][]interface } for rows.Next() { - data := make([]interface{}, length) - dbArgs := make([]interface{}, length) + data := make([]any, length) + dbArgs := make([]any, length) - for i := 0; i < length; i++ { + for i := range length { dbArgs[i] = &data[i] } @@ -123,14 +123,14 @@ func genDeleteSqls(table *table, db *sql.DB, count int) ([]string, [][]interface return sqls, args, nil } -func genUpdateSqls(table *table, db *sql.DB, count int) ([]string, [][]interface{}, error) { +func genUpdateSqls(table *table, db *sql.DB, count int) ([]string, [][]any, error) { nums, err := queryCount(table, db) if err != nil { return nil, nil, errors.Trace(err) } var sqls []string - var args [][]interface{} + var args [][]any if nums == 0 || nums-count < 1 { return sqls, args, nil @@ -146,10 +146,10 @@ func genUpdateSqls(table *table, db *sql.DB, count int) ([]string, [][]interface } for rows.Next() { - data := make([]interface{}, length) - dbArgs := make([]interface{}, length) + data := make([]any, length) + dbArgs := make([]any, length) - for i := 0; i < length; i++ { + for i := range length { dbArgs[i] = &data[i] } @@ -172,10 +172,10 @@ func genUpdateSqls(table *table, db *sql.DB, count int) ([]string, [][]interface return sqls, args, nil } -func genInsertSqls(table *table, count int) ([]string, [][]interface{}, error) { +func genInsertSqls(table *table, count int) ([]string, [][]any, error) { datas := make([]string, 0, count) - args := make([][]interface{}, 0, count) - for i := 0; i < count; i++ { + args := make([][]any, 0, count) + for range count { data, err := genRowData(table) if err != nil { return nil, nil, errors.Trace(err) diff --git a/tests/integration_tests/cdc/dailytest/job.go b/tests/integration_tests/cdc/dailytest/job.go index 6e3243ee2a..92a5c6a8c7 100644 --- a/tests/integration_tests/cdc/dailytest/job.go +++ b/tests/integration_tests/cdc/dailytest/job.go @@ -24,7 +24,7 @@ import ( ) func addJobs(jobCount int, jobChan chan struct{}) { - for i := 0; i < jobCount; i++ { + for range jobCount { jobChan <- struct{}{} } @@ -33,7 +33,7 @@ func addJobs(jobCount int, jobChan chan struct{}) { func doSqls(table *table, db *sql.DB, count int) { var sqls []string - var args [][]interface{} + var args [][]any var err error sql, arg, err := genDeleteSqls(table, db, count/10) @@ -63,7 +63,7 @@ func doSqls(table *table, db *sql.DB, count int) { execSqls(db, sqls, args) } -func execSqls(db *sql.DB, sqls []string, args [][]interface{}) { +func execSqls(db *sql.DB, sqls []string, args [][]any) { txn, err := db.Begin() if err != nil { log.S().Fatalf(errors.ErrorStack(err)) @@ -100,7 +100,7 @@ func doJob(table *table, db *sql.DB, batch int, jobChan chan struct{}, doneChan } func doWait(doneChan chan struct{}, workerCount int) { - for i := 0; i < workerCount; i++ { + for range workerCount { <-doneChan } @@ -113,7 +113,7 @@ func doDMLProcess(table *table, db *sql.DB, jobCount int, workerCount int, batch go addJobs(jobCount, jobChan) - for i := 0; i < workerCount; i++ { + for range workerCount { go doJob(table, db, batch, jobChan, doneChan) } @@ -133,7 +133,7 @@ func doDDLProcess(table *table, db *sql.DB) { newCols = append(newCols, table.columns[index+1:]...) table.columns = newCols sql := fmt.Sprintf("alter table %s drop column %s", table.name, col.name) - execSqls(db, []string{sql}, [][]interface{}{{}}) + execSqls(db, []string{sql}, [][]any{{}}) } // do add column ddl @@ -150,7 +150,7 @@ func doDDLProcess(table *table, db *sql.DB) { table.columns = newCols sql := fmt.Sprintf("alter table %s add column `%s` varchar(45) after %s", table.name, col.name, table.columns[index-1].name) - execSqls(db, []string{sql}, [][]interface{}{{}}) + execSqls(db, []string{sql}, [][]any{{}}) } func doProcess(table *table, db *sql.DB, jobCount int, workerCount int, batch int) { diff --git a/tests/integration_tests/cdc/dailytest/parser.go b/tests/integration_tests/cdc/dailytest/parser.go index 7ff2840309..867e7f05e8 100644 --- a/tests/integration_tests/cdc/dailytest/parser.go +++ b/tests/integration_tests/cdc/dailytest/parser.go @@ -71,8 +71,8 @@ func (col *column) parseRule(kvs []string) { log.S().Fatal(err) } } else if key == "set" { - fields := strings.Split(value, ",") - for _, field := range fields { + fields := strings.SplitSeq(value, ",") + for field := range fields { col.set = append(col.set, strings.TrimSpace(field)) } } @@ -90,8 +90,8 @@ func (col *column) parseColumnComment() { content = comment[start+2 : end] } - fields := strings.Split(content, ";") - for _, field := range fields { + fields := strings.SplitSeq(content, ";") + for field := range fields { field = strings.TrimSpace(field) kvs := strings.Split(field, "=") col.parseRule(kvs) @@ -127,12 +127,12 @@ type table struct { } func (t *table) printColumns() string { - ret := "" + var ret strings.Builder for _, col := range t.columns { - ret += fmt.Sprintf("%v", col) + ret.WriteString(fmt.Sprintf("%v", col)) } - return ret + return ret.String() } func (t *table) String() string { @@ -140,23 +140,24 @@ func (t *table) String() string { return "" } - ret := fmt.Sprintf("[table]name: %s\n", t.name) - ret += "[table]columns:\n" - ret += t.printColumns() + var ret strings.Builder + ret.WriteString(fmt.Sprintf("[table]name: %s\n", t.name)) + ret.WriteString("[table]columns:\n") + ret.WriteString(t.printColumns()) - ret += fmt.Sprintf("[table]column list: %s\n", t.columnList) + ret.WriteString(fmt.Sprintf("[table]column list: %s\n", t.columnList)) - ret += "[table]indices:\n" + ret.WriteString("[table]indices:\n") for k, v := range t.indices { - ret += fmt.Sprintf("key->%s, value->%v", k, v) + ret.WriteString(fmt.Sprintf("key->%s, value->%v", k, v)) } - ret += "[table]unique indices:\n" + ret.WriteString("[table]unique indices:\n") for k, v := range t.uniqIndices { - ret += fmt.Sprintf("key->%s, value->%v", k, v) + ret.WriteString(fmt.Sprintf("key->%s, value->%v", k, v)) } - return ret + return ret.String() } func newTable() *table { diff --git a/tests/integration_tests/ddl_wait/test.go b/tests/integration_tests/ddl_wait/test.go index 204e385a03..247e704b3d 100644 --- a/tests/integration_tests/ddl_wait/test.go +++ b/tests/integration_tests/ddl_wait/test.go @@ -72,11 +72,11 @@ func run(host string, port string) { } var wg sync.WaitGroup - for k := 0; k < concurrency; k++ { + for k := range concurrency { wg.Add(1) go func(k int) { defer wg.Done() - for i := 0; i < num; i++ { + for i := range num { val := k*num + i _, err = db.Exec(insertDML, val, val) if err != nil { diff --git a/tests/integration_tests/ddl_with_exists/test.go b/tests/integration_tests/ddl_with_exists/test.go index e7c018e49d..68c288ed12 100644 --- a/tests/integration_tests/ddl_with_exists/test.go +++ b/tests/integration_tests/ddl_with_exists/test.go @@ -54,7 +54,7 @@ func main() { db.SetMaxOpenConns(concurrency) start := time.Now() - for i := 0; i < maxTableCnt; i++ { + for i := range maxTableCnt { _, err := db.Exec(fmt.Sprintf(createTable, i)) if err != nil { log.Fatal("create table failed:", i, ", err: ", err) @@ -63,12 +63,10 @@ func main() { log.Println("create table cost:", time.Since(start).Seconds(), "s") var wg sync.WaitGroup - for i := 0; i < concurrency; i++ { - wg.Add(1) - go func() { - defer wg.Done() + for i := range concurrency { + wg.Go(func() { log.Println("worker start:", i) - for j := 0; j < 20; j++ { + for range 20 { idx := rand.Intn(maxTableCnt) ddl := fmt.Sprintf(createTable, idx) switch rand.Intn(5) { @@ -88,7 +86,7 @@ func main() { } } log.Println("worker exit:", i) - }() + }) } wg.Wait() } diff --git a/tests/integration_tests/default_value/main.go b/tests/integration_tests/default_value/main.go index b6b6dd6f4a..956151490f 100644 --- a/tests/integration_tests/default_value/main.go +++ b/tests/integration_tests/default_value/main.go @@ -111,12 +111,10 @@ func testGetDefaultValue(srcs []*sql.DB, wg *sync.WaitGroup) { time.Sleep(5 * time.Millisecond) - wg1.Add(1) - go func() { + wg1.Go(func() { ddlFunc(ctx, srcs[0]) cancel() - wg1.Done() - }() + }) wg1.Wait() @@ -126,7 +124,7 @@ func testGetDefaultValue(srcs []*sql.DB, wg *sync.WaitGroup) { wg2.Wait() } -func getFunctionName(i interface{}) string { +func getFunctionName(i any) string { strs := strings.Split(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name(), ".") return strs[len(strs)-1] } @@ -146,7 +144,7 @@ func ignoreableError(err error) bool { } // TODO: need cover the scenarios: update existing old value -func dml(ctx context.Context, db *sql.DB, table string, id int, defaultValue interface{}) { +func dml(ctx context.Context, db *sql.DB, table string, id int, defaultValue any) { var err error var i int var insertSuccess int @@ -237,7 +235,7 @@ func modifyColumnDefaultValueDDL1(ctx context.Context, db *sql.DB) { default: } - var defaultValue interface{} + var defaultValue any if value%2 != 0 { defaultValue = value @@ -277,7 +275,7 @@ func modifyColumnDefaultValueDDL2(ctx context.Context, db *sql.DB) { default: } - var defaultValue interface{} + var defaultValue any if value%2 != 0 { defaultValue = value @@ -294,7 +292,7 @@ func modifyColumnDefaultValueDDL2(ctx context.Context, db *sql.DB) { } func ddlZeroValueFunc(ctx context.Context, db *sql.DB, format string, table string, - defaultValue interface{}, + defaultValue any, ) { // drop column at first fm := fmt.Sprintf("alter table test.`%s` drop column v1", table) @@ -318,7 +316,7 @@ func ddlZeroValueFunc(ctx context.Context, db *sql.DB, format string, table stri } func ddlDefaultValueFunc(ctx context.Context, db *sql.DB, format string, table string, - defaultValue interface{}, + defaultValue any, ) { for value := 1; value < 3; value++ { select { @@ -347,8 +345,8 @@ func testMultiDDLs(srcs []*sql.DB, wg *sync.WaitGroup) { type Unit struct { Fmt string - DefaultValue interface{} - DDLFunc func(context.Context, *sql.DB, string, string, interface{}) + DefaultValue any + DDLFunc func(context.Context, *sql.DB, string, string, any) NoDMLParas bool } @@ -853,12 +851,10 @@ func testMultiDDLs(srcs []*sql.DB, wg *sync.WaitGroup) { time.Sleep(5 * time.Millisecond) // start ddl - wg2.Add(1) - go func() { + wg2.Go(func() { unit.DDLFunc(ctx, srcs[0], unit.Fmt, newTbName, unit.DefaultValue) cancel2() - wg2.Done() - }() + }) wg2.Wait() }) diff --git a/tests/integration_tests/http_proxies/run-proxy.go b/tests/integration_tests/http_proxies/run-proxy.go index b7d244426f..e323efe912 100644 --- a/tests/integration_tests/http_proxies/run-proxy.go +++ b/tests/integration_tests/http_proxies/run-proxy.go @@ -48,7 +48,7 @@ func main() { fmt.Println("proxy started") } -func intercept(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { +func intercept(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { fmt.Println(info.FullMethod) err := handler(srv, ss) if err != nil { diff --git a/tests/integration_tests/many_pk_or_uk/main.go b/tests/integration_tests/many_pk_or_uk/main.go index aa00fe7281..7a83b30327 100644 --- a/tests/integration_tests/many_pk_or_uk/main.go +++ b/tests/integration_tests/many_pk_or_uk/main.go @@ -57,8 +57,8 @@ func main() { func runPKorUKcases(db *sql.DB) { cases := []struct { Tp string - Value interface{} - Update interface{} + Value any + Update any }{ { Tp: "BIGINT UNSIGNED", diff --git a/tests/integration_tests/multi_source/main.go b/tests/integration_tests/multi_source/main.go index df1e4c13d9..4d0ad4fe3e 100644 --- a/tests/integration_tests/multi_source/main.go +++ b/tests/integration_tests/multi_source/main.go @@ -98,11 +98,9 @@ func runDDLTest(srcs []*sql.DB) { time.Sleep(time.Millisecond) - wg.Add(1) - go func() { + wg.Go(func() { ddlFunc(ctx, srcs[0]) - wg.Done() - }() + }) wg.Wait() time.Sleep(5 * time.Second) @@ -131,7 +129,7 @@ func switchAsyncCommit(ctx context.Context, db *sql.DB) { } } -func getFunctionName(i interface{}) string { +func getFunctionName(i any) string { strs := strings.Split(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name(), ".") return strs[len(strs)-1] } @@ -213,7 +211,7 @@ func dml(ctx context.Context, db *sql.DB, table string, id int) { insertSQL := fmt.Sprintf("insert into test.`%s`(id, id1, id2) values(?,?,?)", table) deleteSQL := fmt.Sprintf("delete from test.`%s` where id1 = ? or id2 = ?", table) k := 100000000 - for i = 0; i < k; i++ { + for i = range k { _, err = db.Exec(insertSQL, i+id*k, i+id*k, i+id*k+1) if err == nil { insertSuccess++ @@ -264,7 +262,7 @@ func addDropColumnDDL(ctx context.Context, db *sql.DB) { time.Sleep(100 * time.Millisecond) var notNULL string - var defaultValue interface{} + var defaultValue any if value%5 == 0 { // use default not null @@ -306,7 +304,7 @@ func addDropColumnDDL2(ctx context.Context, db *sql.DB) { time.Sleep(100 * time.Millisecond) var notNULL string - var defaultValue interface{} + var defaultValue any strValue := strconv.Itoa(value) if value%5 == 0 { @@ -337,7 +335,7 @@ func modifyColumnDDL(ctx context.Context, db *sql.DB) { default: } - var defaultValue interface{} + var defaultValue any // use default null per five modify if value%5 == 0 { defaultValue = nil diff --git a/tests/integration_tests/resolve_lock/main.go b/tests/integration_tests/resolve_lock/main.go index d877df3885..fd7438f58d 100644 --- a/tests/integration_tests/resolve_lock/main.go +++ b/tests/integration_tests/resolve_lock/main.go @@ -333,9 +333,9 @@ func (c *Locker) lockBatch(ctx context.Context, keys [][]byte, primary []byte) ( func randStr() string { length := rand.Intn(128) - res := "" - for i := 0; i < length; i++ { - res += fmt.Sprintf("a%d", rand.Intn(26)) + var res strings.Builder + for range length { + res.WriteString(fmt.Sprintf("a%d", rand.Intn(26))) } - return res + return res.String() } diff --git a/tests/integration_tests/util/db.go b/tests/integration_tests/util/db.go index 4f61d6d8dd..0c532d0f90 100644 --- a/tests/integration_tests/util/db.go +++ b/tests/integration_tests/util/db.go @@ -141,7 +141,7 @@ func CheckSyncState(sourceDB, targetDB *sql.DB, schema string) bool { } // MustExec executes sqls -func MustExec(db *sql.DB, sql string, args ...interface{}) { +func MustExec(db *sql.DB, sql string, args ...any) { _, err := db.Exec(sql, args...) if err != nil { log.S().Fatalf("exec failed, sql: %s args: %v, err: %+v", sql, args, err) @@ -149,7 +149,7 @@ func MustExec(db *sql.DB, sql string, args ...interface{}) { } // MustExecWithConn executes sqls with context -func MustExecWithConn(ctx context.Context, conn *sql.Conn, sql string, args ...interface{}) { +func MustExecWithConn(ctx context.Context, conn *sql.Conn, sql string, args ...any) { var err error _, err = conn.ExecContext(ctx, sql, args...) if err != nil && errors.Cause(err) == context.DeadlineExceeded && errors.Cause(err) == context.Canceled { diff --git a/tests/mq_protocol_tests/cases/case_alter.go b/tests/mq_protocol_tests/cases/case_alter.go index 5cb2b03854..fa58966e49 100644 --- a/tests/mq_protocol_tests/cases/case_alter.go +++ b/tests/mq_protocol_tests/cases/case_alter.go @@ -45,7 +45,7 @@ func (c *AlterCase) Run(ctx *framework.TaskContext) error { return err } - for i := 0; i < 20; i++ { + for i := range 20 { _, err := ctx.Upstream.ExecContext(ctx.Ctx, fmt.Sprintf("alter table test add column (value%d int)", i)) if err != nil { return err @@ -53,8 +53,8 @@ func (c *AlterCase) Run(ctx *framework.TaskContext) error { table := ctx.SQLHelper().GetTable("test") reqs := make([]framework.Awaitable, 0) - for j := 0; j < 1000; j++ { - rowData := make(map[string]interface{}, i+1) + for j := range 1000 { + rowData := make(map[string]any, i+1) rowData["id"] = i*1000 + j for k := 0; k <= i; k++ { rowData[fmt.Sprintf("value%d", k)] = rand.Int31() diff --git a/tests/mq_protocol_tests/cases/case_composite_pkey.go b/tests/mq_protocol_tests/cases/case_composite_pkey.go index 8c49f39d23..45594c0bc2 100644 --- a/tests/mq_protocol_tests/cases/case_composite_pkey.go +++ b/tests/mq_protocol_tests/cases/case_composite_pkey.go @@ -45,7 +45,7 @@ func (s *CompositePKeyCase) Run(ctx *framework.TaskContext) error { // Get a handle of an existing table table := ctx.SQLHelper().GetTable("test") // Create an SQL request, send it to the upstream, wait for completion and check the correctness of replication - err = table.Insert(map[string]interface{}{ + err = table.Insert(map[string]any{ "id1": 0, "id2": 1, "value": 0, @@ -54,7 +54,7 @@ func (s *CompositePKeyCase) Run(ctx *framework.TaskContext) error { return errors.AddStack(err) } - err = table.Upsert(map[string]interface{}{ + err = table.Upsert(map[string]any{ "id1": 0, "id2": 1, "value": 1, @@ -63,7 +63,7 @@ func (s *CompositePKeyCase) Run(ctx *framework.TaskContext) error { return err } - err = table.Delete(map[string]interface{}{ + err = table.Delete(map[string]any{ "id1": 0, "id2": 1, }).Send().Wait().Check() diff --git a/tests/mq_protocol_tests/cases/case_date_time.go b/tests/mq_protocol_tests/cases/case_date_time.go index 65c23c1b3c..b0bbfa7143 100644 --- a/tests/mq_protocol_tests/cases/case_date_time.go +++ b/tests/mq_protocol_tests/cases/case_date_time.go @@ -80,7 +80,7 @@ func (s *DateTimeCase) Run(ctx *framework.TaskContext) error { // Zero value case zeroValue := time.Unix(0, 0) - data := map[string]interface{}{ + data := map[string]any{ "id": 0, "t_date": zeroValue, "t_datetime": zeroValue, diff --git a/tests/mq_protocol_tests/cases/case_delete.go b/tests/mq_protocol_tests/cases/case_delete.go index 3a0e6702a1..5447c11ed0 100644 --- a/tests/mq_protocol_tests/cases/case_delete.go +++ b/tests/mq_protocol_tests/cases/case_delete.go @@ -49,9 +49,9 @@ func (c *DeleteCase) Run(ctx *framework.TaskContext) error { // To wait on a batch of SQL requests, create a slice of Awaitables reqs := make([]framework.Awaitable, 0) - for i := 0; i < 1000; i++ { + for i := range 1000 { // Only send, do not wait - req := table.Insert(map[string]interface{}{ + req := table.Insert(map[string]any{ "id": i, "value": i, }).Send() @@ -64,8 +64,8 @@ func (c *DeleteCase) Run(ctx *framework.TaskContext) error { } deletes := make([]framework.Awaitable, 0, 1000) - for i := 0; i < 1000; i++ { - req := table.Delete(map[string]interface{}{ + for i := range 1000 { + req := table.Delete(map[string]any{ "id": i, }).Send() deletes = append(deletes, req) diff --git a/tests/mq_protocol_tests/cases/case_handle_key.go b/tests/mq_protocol_tests/cases/case_handle_key.go index 50f50a13e0..a2679823df 100644 --- a/tests/mq_protocol_tests/cases/case_handle_key.go +++ b/tests/mq_protocol_tests/cases/case_handle_key.go @@ -45,7 +45,7 @@ func (s *HandleKeyCase) Run(ctx *framework.TaskContext) error { // Get a handle of an existing table table := ctx.SQLHelper().GetTable("test") // Create an SQL request, send it to the upstream, wait for completion and check the correctness of replication - err = table.Insert(map[string]interface{}{ + err = table.Insert(map[string]any{ "id": 0, "value": 0, }).Send().Wait().Check() @@ -53,7 +53,7 @@ func (s *HandleKeyCase) Run(ctx *framework.TaskContext) error { return errors.AddStack(err) } - err = table.Upsert(map[string]interface{}{ + err = table.Upsert(map[string]any{ "id": 0, "value": 1, }).Send().Wait().Check() @@ -61,7 +61,7 @@ func (s *HandleKeyCase) Run(ctx *framework.TaskContext) error { return err } - err = table.Delete(map[string]interface{}{ + err = table.Delete(map[string]any{ "id": 0, }).Send().Wait().Check() return err diff --git a/tests/mq_protocol_tests/cases/case_many_types.go b/tests/mq_protocol_tests/cases/case_many_types.go index 63548ea8f2..0d88162efb 100644 --- a/tests/mq_protocol_tests/cases/case_many_types.go +++ b/tests/mq_protocol_tests/cases/case_many_types.go @@ -152,7 +152,7 @@ func (s *ManyTypesCase) Run(ctx *framework.TaskContext) error { // Get a handle of an existing table table := ctx.SQLHelper().GetTable("test") - data := map[string]interface{}{ + data := map[string]any{ "id": 0, "t_boolean": true, "t_bigint": math.MaxInt64, diff --git a/tests/mq_protocol_tests/cases/case_simple.go b/tests/mq_protocol_tests/cases/case_simple.go index d9f10a45e2..957b9341f4 100644 --- a/tests/mq_protocol_tests/cases/case_simple.go +++ b/tests/mq_protocol_tests/cases/case_simple.go @@ -45,7 +45,7 @@ func (s *SimpleCase) Run(ctx *framework.TaskContext) error { // Get a handle of an existing table table := ctx.SQLHelper().GetTable("test") // Create an SQL request, send it to the upstream, wait for completion and check the correctness of replication - err = table.Insert(map[string]interface{}{ + err = table.Insert(map[string]any{ "id": 0, "value": 0, }).Send().Wait().Check() @@ -57,7 +57,7 @@ func (s *SimpleCase) Run(ctx *framework.TaskContext) error { reqs := make([]framework.Awaitable, 0) for i := 1; i < 1000; i++ { // Only send, do not wait - req := table.Insert(map[string]interface{}{ + req := table.Insert(map[string]any{ "id": i, "value": i, }).Send() @@ -70,7 +70,7 @@ func (s *SimpleCase) Run(ctx *framework.TaskContext) error { return err } - err = table.Upsert(map[string]interface{}{ + err = table.Upsert(map[string]any{ "id": 0, "value": 1, }).Send().Wait().Check() @@ -78,7 +78,7 @@ func (s *SimpleCase) Run(ctx *framework.TaskContext) error { return err } - err = table.Delete(map[string]interface{}{ + err = table.Delete(map[string]any{ "id": 0, }).Send().Wait().Check() return err diff --git a/tests/mq_protocol_tests/cases/case_unsigned.go b/tests/mq_protocol_tests/cases/case_unsigned.go index 3e9c7f7d14..a1757f8bf7 100644 --- a/tests/mq_protocol_tests/cases/case_unsigned.go +++ b/tests/mq_protocol_tests/cases/case_unsigned.go @@ -61,7 +61,7 @@ func (s *UnsignedCase) Run(ctx *framework.TaskContext) error { // Get a handle of an existing table table := ctx.SQLHelper().GetTable("test") - return table.Insert(map[string]interface{}{ + return table.Insert(map[string]any{ "id": 0, "t_int": 0xFEEDBEEF, "t_bigint": uint64(0xFEEDBEEFFEEDBEEF), diff --git a/tests/mq_protocol_tests/framework/avro/kafka_docker_env.go b/tests/mq_protocol_tests/framework/avro/kafka_docker_env.go index ea5006439f..4d93ebb108 100644 --- a/tests/mq_protocol_tests/framework/avro/kafka_docker_env.go +++ b/tests/mq_protocol_tests/framework/avro/kafka_docker_env.go @@ -54,7 +54,7 @@ func NewKafkaDockerEnv(dockerComposeFile string) *KafkaDockerEnv { return err } - m := make(map[string]interface{}) + m := make(map[string]any) err = json.Unmarshal(bytes, &m) if err != nil { return err diff --git a/tests/mq_protocol_tests/framework/docker_env.go b/tests/mq_protocol_tests/framework/docker_env.go index 06d7365ee9..3260949be3 100644 --- a/tests/mq_protocol_tests/framework/docker_env.go +++ b/tests/mq_protocol_tests/framework/docker_env.go @@ -121,7 +121,7 @@ func (e *DockerEnv) RunTest(task Task) { } // SetListener implements Environment. Currently unfinished, will be used to monitor Kafka output -func (e *DockerEnv) SetListener(states interface{}, listener MqListener) { +func (e *DockerEnv) SetListener(states any, listener MqListener) { // TODO } diff --git a/tests/mq_protocol_tests/framework/env.go b/tests/mq_protocol_tests/framework/env.go index 1bf466c7fa..f5a8a83a1a 100644 --- a/tests/mq_protocol_tests/framework/env.go +++ b/tests/mq_protocol_tests/framework/env.go @@ -14,7 +14,7 @@ package framework // MqListener represents a callback function for listening on the MQ output -type MqListener func(states interface{}, topic string, key []byte, value []byte) error +type MqListener func(states any, topic string, key []byte, value []byte) error // Environment is an abstract of the CDC-Upstream-Downstream-MQ complex to be tested type Environment interface { @@ -22,5 +22,5 @@ type Environment interface { TearDown() Reset() RunTest(Task) - SetListener(states interface{}, listener MqListener) + SetListener(states any, listener MqListener) } diff --git a/tests/mq_protocol_tests/framework/sql_batch_op.go b/tests/mq_protocol_tests/framework/sql_batch_op.go index e05c9072c9..a3cc1e4be9 100644 --- a/tests/mq_protocol_tests/framework/sql_batch_op.go +++ b/tests/mq_protocol_tests/framework/sql_batch_op.go @@ -32,8 +32,8 @@ const ( type sqlAllAwaiter struct { helper *SQLHelper - data map[interface{}]sqlRowContainer - retrievedValues []map[string]interface{} + data map[any]sqlRowContainer + retrievedValues []map[string]any table *Table } @@ -46,8 +46,8 @@ func All(helper *SQLHelper, awaitables []Awaitable) Awaitable { ret := &sqlAllAwaiter{ helper: helper, - data: make(map[interface{}]sqlRowContainer, len(awaitables)), - retrievedValues: make([]map[string]interface{}, 0), + data: make(map[any]sqlRowContainer, len(awaitables)), + retrievedValues: make([]map[string]any, 0), table: awaitables[0].(sqlRowContainer).getTable(), } @@ -71,8 +71,8 @@ func (s *sqlAllAwaiter) poll(ctx context.Context) (bool, error) { batchSize := 0 counter := 0 - indexValues := make([]interface{}, 0) - s.retrievedValues = make([]map[string]interface{}, 0) + indexValues := make([]any, 0) + s.retrievedValues = make([]map[string]any, 0) for k, v := range s.data { indexValues = append(indexValues, k) batchSize++ @@ -101,7 +101,7 @@ func (s *sqlAllAwaiter) poll(ctx context.Context) (bool, error) { s.retrievedValues = append(s.retrievedValues, m) } batchSize = 0 - indexValues = make([]interface{}, 0) + indexValues = make([]any, 0) } } @@ -130,7 +130,7 @@ func (s *sqlAllAwaiter) Check() error { return nil } -func normalizeKeys(key interface{}) interface{} { +func normalizeKeys(key any) any { switch key.(type) { case int, int8, int16, int32, int64: return reflect.ValueOf(key).Int() diff --git a/tests/mq_protocol_tests/framework/sql_helper.go b/tests/mq_protocol_tests/framework/sql_helper.go index d05e8b4dd8..716a6aa499 100644 --- a/tests/mq_protocol_tests/framework/sql_helper.go +++ b/tests/mq_protocol_tests/framework/sql_helper.go @@ -61,7 +61,7 @@ func (h *SQLHelper) GetTable(tableName string) *Table { return &Table{tableName: tableName, uniqueIndex: idxCol, helper: h} } -func (t *Table) makeSQLRequest(requestType sqlRequestType, rowData map[string]interface{}) (*sqlRequest, error) { +func (t *Table) makeSQLRequest(requestType sqlRequestType, rowData map[string]any) (*sqlRequest, error) { if t.err != nil { return nil, t.err } @@ -77,7 +77,7 @@ func (t *Table) makeSQLRequest(requestType sqlRequestType, rowData map[string]in } // Insert returns a Sendable object that represents an Insert clause -func (t *Table) Insert(rowData map[string]interface{}) Sendable { +func (t *Table) Insert(rowData map[string]any) Sendable { basicReq, err := t.makeSQLRequest(sqlRequestTypeInsert, rowData) if err != nil { return &errorSender{err: err} @@ -87,7 +87,7 @@ func (t *Table) Insert(rowData map[string]interface{}) Sendable { } // Upsert returns a Sendable object that represents a Replace Into clause -func (t *Table) Upsert(rowData map[string]interface{}) Sendable { +func (t *Table) Upsert(rowData map[string]any) Sendable { basicReq, err := t.makeSQLRequest(sqlRequestTypeUpsert, rowData) if err != nil { return &errorSender{err: err} @@ -97,7 +97,7 @@ func (t *Table) Upsert(rowData map[string]interface{}) Sendable { } // Delete returns a Sendable object that represents a Delete from clause -func (t *Table) Delete(rowData map[string]interface{}) Sendable { +func (t *Table) Delete(rowData map[string]any) Sendable { basicReq, err := t.makeSQLRequest(sqlRequestTypeDelete, rowData) if err != nil { return &errorSender{err: err} @@ -107,7 +107,7 @@ func (t *Table) Delete(rowData map[string]interface{}) Sendable { } type sqlRowContainer interface { - getData() map[string]interface{} + getData() map[string]any getComparableKey() string getTable() *Table } @@ -127,8 +127,8 @@ const ( type sqlRequest struct { tableName string - data map[string]interface{} - result map[string]interface{} + data map[string]any + result map[string]any uniqueIndex []string helper *SQLHelper requestType sqlRequestType @@ -146,9 +146,9 @@ func (s *sqlRequest) getPrimaryKeyTuple() string { return makeColumnTuple(s.uniqueIndex) } -func (s *sqlRequest) getWhereCondition() []interface{} { +func (s *sqlRequest) getWhereCondition() []any { builder := strings.Builder{} - args := make([]interface{}, 1, len(s.uniqueIndex)+1) + args := make([]any, 1, len(s.uniqueIndex)+1) builder.WriteString(s.getPrimaryKeyTuple() + " = (") for i, col := range s.uniqueIndex { builder.WriteString("?") @@ -168,7 +168,7 @@ func (s *sqlRequest) getComparableKey() string { return s.uniqueIndex[0] } - ret := make(map[string]interface{}) + ret := make(map[string]any) for k, v := range s.data { for _, col := range s.uniqueIndex { if k == col { @@ -179,7 +179,7 @@ func (s *sqlRequest) getComparableKey() string { return fmt.Sprintf("%v", ret) } -func (s *sqlRequest) getData() map[string]interface{} { +func (s *sqlRequest) getData() map[string]any { return s.data } @@ -283,7 +283,7 @@ func (s *sqlRequest) insert(ctx context.Context) error { } keys := make([]string, len(s.data)) - values := make([]interface{}, len(s.data)) + values := make([]any, len(s.data)) i := 0 for k, v := range s.data { keys[i] = k @@ -304,7 +304,7 @@ func (s *sqlRequest) upsert(ctx context.Context) error { db := sqlx.NewDb(s.helper.upstream, "mysql") keys := make([]string, len(s.data)) - values := make([]interface{}, len(s.data)) + values := make([]any, len(s.data)) i := 0 for k, v := range s.data { keys[i] = k @@ -342,7 +342,7 @@ func (s *sqlRequest) delete(ctx context.Context) error { return nil } -func (s *sqlRequest) read(ctx context.Context) (map[string]interface{}, error) { +func (s *sqlRequest) read(ctx context.Context) (map[string]any, error) { db, err := sqlbuilder.New("mysql", s.helper.downstream) if err != nil { return nil, errors.AddStack(err) @@ -421,14 +421,14 @@ func (s *sqlRequest) Check() error { return errors.New("Check failed") } -func rowsToMap(rows *sql.Rows) (map[string]interface{}, error) { +func rowsToMap(rows *sql.Rows) (map[string]any, error) { colNames, err := rows.Columns() if err != nil { return nil, errors.AddStack(err) } - colData := make([]interface{}, len(colNames)) - colDataPtrs := make([]interface{}, len(colNames)) + colData := make([]any, len(colNames)) + colDataPtrs := make([]any, len(colNames)) for i := range colData { colDataPtrs[i] = &colData[i] } @@ -438,8 +438,8 @@ func rowsToMap(rows *sql.Rows) (map[string]interface{}, error) { return nil, errors.AddStack(err) } - ret := make(map[string]interface{}, len(colNames)) - for i := 0; i < len(colNames); i++ { + ret := make(map[string]any, len(colNames)) + for i := range colNames { ret[colNames[i]] = colData[i] } return ret, nil @@ -465,7 +465,7 @@ func getUniqueIndexColumn(ctx context.Context, db sqlbuilder.Database, dbName st return strings.Split(colName, " "), nil } -func compareMaps(m1 map[string]interface{}, m2 map[string]interface{}) bool { +func compareMaps(m1 map[string]any, m2 map[string]any) bool { // TODO better comparator if m2 == nil { return false From aa04847d880e0b101910b42b3a082f886b8db089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Mon, 15 Jun 2026 10:28:15 +0200 Subject: [PATCH 2/9] Run make fmt --- dm/config/subtask_test.go | 2 -- dm/ctl/master/operate_task.go | 1 - engine/framework/internal/eventloop/runner_test.go | 2 -- engine/framework/internal/worker/master_client_test.go | 1 - engine/internal/pkg/discovery/agent_test.go | 1 - engine/jobmaster/dm/api.go | 1 - engine/pkg/client/internal/call_test.go | 2 -- engine/pkg/containers/slice_queue_test.go | 2 -- engine/pkg/errctx/center_test.go | 2 -- engine/pkg/externalresource/integration_test/mock_cluster.go | 2 -- engine/pkg/externalresource/manager/gc_coordinator_test.go | 1 - engine/pkg/externalresource/manager/gc_runner_test.go | 1 - engine/pkg/notifier/notifier_test.go | 2 -- engine/servermaster/executor_manager.go | 1 - engine/servermaster/serverutil/watch_executors_test.go | 1 - pkg/chdelay/channel_delayer_test.go | 1 - pkg/p2p/server_client_integration_test.go | 1 - 17 files changed, 24 deletions(-) diff --git a/dm/config/subtask_test.go b/dm/config/subtask_test.go index 5d40d6e4e6..3efb320be0 100644 --- a/dm/config/subtask_test.go +++ b/dm/config/subtask_test.go @@ -464,7 +464,6 @@ func TestSubTaskConfigMarshalAtomic(t *testing.T) { var wg sync.WaitGroup for range 10 { wg.Go(func() { - data, err := json.Marshal(cfg) require.NoError(t, err) jsonMap := make(map[string]any) @@ -488,7 +487,6 @@ func TestSubTaskConfigMarshalAtomic(t *testing.T) { }) wg.Go(func() { - newCfg, err := cfg.Clone() require.NoError(t, err) diff --git a/dm/ctl/master/operate_task.go b/dm/ctl/master/operate_task.go index e72e62abd4..7a97bbadf9 100644 --- a/dm/ctl/master/operate_task.go +++ b/dm/ctl/master/operate_task.go @@ -127,7 +127,6 @@ func batchOperateTask(taskOp pb.TaskOp, batchSize int, sources []string, subTask resultCh := make(chan *operateTaskResult, 1) for i := 0; i < batchSize; i++ { wg.Go(func() { - for name := range workCh { taskResult := operateTaskResult{Task: name, Op: taskOp.String()} taskOpResp, err := common.OperateTask(taskOp, name, sources) diff --git a/engine/framework/internal/eventloop/runner_test.go b/engine/framework/internal/eventloop/runner_test.go index e328ace423..614ec9236c 100644 --- a/engine/framework/internal/eventloop/runner_test.go +++ b/engine/framework/internal/eventloop/runner_test.go @@ -119,7 +119,6 @@ func TestRunnerNormalPath(t *testing.T) { var wg sync.WaitGroup wg.Go(func() { - err := runner.Run(context.Background()) require.Error(t, err) require.Regexp(t, "injected error", err) @@ -152,7 +151,6 @@ func TestRunnerForcefulExit(t *testing.T) { var wg sync.WaitGroup wg.Go(func() { - err := runner.Run(context.Background()) require.Error(t, err) require.Regexp(t, "ErrWorkerSuicide", err) diff --git a/engine/framework/internal/worker/master_client_test.go b/engine/framework/internal/worker/master_client_test.go index b9c505ff70..4caff5d8cc 100644 --- a/engine/framework/internal/worker/master_client_test.go +++ b/engine/framework/internal/worker/master_client_test.go @@ -92,7 +92,6 @@ func (h *masterClientTestHelper) PopHeartbeat(t *testing.T) *frameModel.Heartbea func (h *masterClientTestHelper) SimulateWorkerClose(timeout time.Duration) { h.wg.Go(func() { - ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() diff --git a/engine/internal/pkg/discovery/agent_test.go b/engine/internal/pkg/discovery/agent_test.go index cd8798e66a..e4c15c2f6c 100644 --- a/engine/internal/pkg/discovery/agent_test.go +++ b/engine/internal/pkg/discovery/agent_test.go @@ -73,7 +73,6 @@ func TestAgent(t *testing.T) { var wg sync.WaitGroup wg.Go(func() { - err := agent.Run(ctx) require.ErrorIs(t, err, context.Canceled) }) diff --git a/engine/jobmaster/dm/api.go b/engine/jobmaster/dm/api.go index 6fe753a8e7..e11e2795aa 100644 --- a/engine/jobmaster/dm/api.go +++ b/engine/jobmaster/dm/api.go @@ -104,7 +104,6 @@ func (jm *JobMaster) QueryJobStatus(ctx context.Context, tasks []string) (*JobSt for _, task := range tasks { taskID := task wg.Go(func() { - var ( queryStatusResp *dmpkg.QueryStatusResponse workerID string diff --git a/engine/pkg/client/internal/call_test.go b/engine/pkg/client/internal/call_test.go index 286662f36a..1e25ef24e9 100644 --- a/engine/pkg/client/internal/call_test.go +++ b/engine/pkg/client/internal/call_test.go @@ -60,7 +60,6 @@ func TestCallFuncCancel(t *testing.T) { var wg sync.WaitGroup wg.Go(func() { - resp, err := call.Do(ctx) require.Nil(t, resp) require.Error(t, err) @@ -83,7 +82,6 @@ func TestCallRetryCancel(t *testing.T) { var wg sync.WaitGroup wg.Go(func() { - resp, err := call.Do(ctx) require.Nil(t, resp) require.Error(t, err) diff --git a/engine/pkg/containers/slice_queue_test.go b/engine/pkg/containers/slice_queue_test.go index 269e8f18e1..5626f9536e 100644 --- a/engine/pkg/containers/slice_queue_test.go +++ b/engine/pkg/containers/slice_queue_test.go @@ -103,14 +103,12 @@ func TestSliceQueueConcurrentWriteAndRead(t *testing.T) { q := NewSliceQueue[int]() var wg sync.WaitGroup wg.Go(func() { - for i := range numElems { q.Push(i) } }) wg.Go(func() { - counter := 0 for { <-q.C diff --git a/engine/pkg/errctx/center_test.go b/engine/pkg/errctx/center_test.go index 50d5e14b79..a7b98a8a6a 100644 --- a/engine/pkg/errctx/center_test.go +++ b/engine/pkg/errctx/center_test.go @@ -28,7 +28,6 @@ func TestErrCenterMultipleErrCtx(t *testing.T) { var wg sync.WaitGroup for range 10 { wg.Go(func() { - ctx, cancel := center.WithCancelOnFirstError(context.Background()) defer cancel() <-ctx.Done() @@ -53,7 +52,6 @@ func TestErrCenterSingleErrCtx(t *testing.T) { var wg sync.WaitGroup for range 10 { wg.Go(func() { - <-ctx.Done() require.Error(t, ctx.Err()) require.EqualError(t, ctx.Err(), "fake error") diff --git a/engine/pkg/externalresource/integration_test/mock_cluster.go b/engine/pkg/externalresource/integration_test/mock_cluster.go index 5d4987290d..9eda0b1060 100644 --- a/engine/pkg/externalresource/integration_test/mock_cluster.go +++ b/engine/pkg/externalresource/integration_test/mock_cluster.go @@ -83,14 +83,12 @@ func (c *mockCluster) Start(t *testing.T) { c.cancel = cancel c.wg.Go(func() { - err := c.gcCoordinator.Run(ctx) require.Error(t, err) require.True(t, errors.Is(err, context.Canceled)) }) c.wg.Go(func() { - err := c.gcRunner.Run(ctx) require.Error(t, err) require.True(t, errors.Is(err, context.Canceled)) diff --git a/engine/pkg/externalresource/manager/gc_coordinator_test.go b/engine/pkg/externalresource/manager/gc_coordinator_test.go index 330f44f03c..6d009c4896 100644 --- a/engine/pkg/externalresource/manager/gc_coordinator_test.go +++ b/engine/pkg/externalresource/manager/gc_coordinator_test.go @@ -68,7 +68,6 @@ func newGCTestHelper() *gcTestHelper { func (h *gcTestHelper) Start() { h.wg.Go(func() { - h.errCh <- h.Coord.Run(h.ctx) }) } diff --git a/engine/pkg/externalresource/manager/gc_runner_test.go b/engine/pkg/externalresource/manager/gc_runner_test.go index da186185ee..63df348e19 100644 --- a/engine/pkg/externalresource/manager/gc_runner_test.go +++ b/engine/pkg/externalresource/manager/gc_runner_test.go @@ -78,7 +78,6 @@ func newGCRunnerTestHelperWithMeta(meta pkgOrm.ResourceClient) *gcRunnerTestHelp func (h *gcRunnerTestHelper) Start() { h.wg.Go(func() { - h.errCh <- h.Runner.Run(h.ctx) }) } diff --git a/engine/pkg/notifier/notifier_test.go b/engine/pkg/notifier/notifier_test.go index a2ab27b6e7..cf4c36b080 100644 --- a/engine/pkg/notifier/notifier_test.go +++ b/engine/pkg/notifier/notifier_test.go @@ -36,7 +36,6 @@ func TestNotifierBasics(t *testing.T) { for range numReceivers { wg.Go(func() { - r := n.NewReceiver() defer r.Close() @@ -78,7 +77,6 @@ func TestNotifierClose(t *testing.T) { for range numReceivers { wg.Go(func() { - r := n.NewReceiver() defer r.Close() diff --git a/engine/servermaster/executor_manager.go b/engine/servermaster/executor_manager.go index 5a0dd26a4c..81b66256de 100644 --- a/engine/servermaster/executor_manager.go +++ b/engine/servermaster/executor_manager.go @@ -107,7 +107,6 @@ func (e *ExecutorManagerImpl) removeExecutorLocked(id model.ExecutorID) error { // We use ttl mechanism to manage the executor's life cycle. So we can tolerate // that a tombstone executor may be left in the database. e.wg.Go(func() { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() diff --git a/engine/servermaster/serverutil/watch_executors_test.go b/engine/servermaster/serverutil/watch_executors_test.go index 2bd7adf15a..a4ac06b0e6 100644 --- a/engine/servermaster/serverutil/watch_executors_test.go +++ b/engine/servermaster/serverutil/watch_executors_test.go @@ -129,7 +129,6 @@ func TestWatchExecutors(t *testing.T) { var wg sync.WaitGroup wg.Go(func() { - err := WatchExecutors(ctx, watcher, user) require.ErrorIs(t, err, context.Canceled) }) diff --git a/pkg/chdelay/channel_delayer_test.go b/pkg/chdelay/channel_delayer_test.go index 9d657d5ba8..25fddba5fa 100644 --- a/pkg/chdelay/channel_delayer_test.go +++ b/pkg/chdelay/channel_delayer_test.go @@ -47,7 +47,6 @@ func testChannelDelayer(t *testing.T, delayBy time.Duration, count int) { }) wg.Go(func() { - counter := 0 for ts := range delayer.Out() { require.Greater(t, time.Since(ts), delayBy) diff --git a/pkg/p2p/server_client_integration_test.go b/pkg/p2p/server_client_integration_test.go index 3560b94ba1..8e9a51c8b0 100644 --- a/pkg/p2p/server_client_integration_test.go +++ b/pkg/p2p/server_client_integration_test.go @@ -404,7 +404,6 @@ func TestTopicCongested(t *testing.T) { var lastSeq Seq wg.Go(func() { - for range 100 { seq, err := client.SendMessage(ctx, "test-topic-1", &testTopicContent{}) require.NoError(t, err) From 37854dc3896d3de6a531506ef5f9b3ca6e4d6061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:12:18 +0200 Subject: [PATCH 3/9] Update dm/pkg/conn/basedb.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- dm/pkg/conn/basedb.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dm/pkg/conn/basedb.go b/dm/pkg/conn/basedb.go index f5c47d1ea8..fdf7f4ed0d 100644 --- a/dm/pkg/conn/basedb.go +++ b/dm/pkg/conn/basedb.go @@ -116,8 +116,8 @@ func (d *DefaultDBProviderImpl) ApplyWithPingTimeout(config ScopedDBConfig, ping net = config.Net } var dsn strings.Builder - dsn.WriteString(fmt.Sprintf("%s:%s@%s(%s)/?charset=utf8mb4&interpolateParams=true&maxAllowedPacket=0", - config.User, config.Password, net, hostPort)) + fmt.Fprintf(&dsn, "%s:%s@%s(%s)/?charset=utf8mb4&interpolateParams=true&maxAllowedPacket=0", + config.User, config.Password, net, hostPort) doFuncInClose := func() {} if config.Security != nil { From cc8d68d8fb92ec36e6eea918e47327b5ac630e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:13:16 +0200 Subject: [PATCH 4/9] Update cdc/model/owner.go Co-authored-by: kennytm --- cdc/model/owner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdc/model/owner.go b/cdc/model/owner.go index 37cd58505d..0933a94479 100644 --- a/cdc/model/owner.go +++ b/cdc/model/owner.go @@ -261,7 +261,7 @@ func (p ProcessorsInfos) String() string { var s strings.Builder s.WriteString("{") for id, sinfo := range p { - s.WriteString(fmt.Sprintf("%s: %+v,", id, *sinfo)) + fmt.Fprintf(&s, "%s: %+v,", id, *sinfo) } s.WriteString("}") From 3e735a98908d3293acefa4613e742830494c7dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:14:12 +0200 Subject: [PATCH 5/9] Update cmd/oauth2-server/main.go Co-authored-by: kennytm --- cmd/oauth2-server/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/oauth2-server/main.go b/cmd/oauth2-server/main.go index f8018cf7ab..31b355a173 100644 --- a/cmd/oauth2-server/main.go +++ b/cmd/oauth2-server/main.go @@ -152,7 +152,7 @@ func run(_ *cobra.Command, _ []string) { } }))) http.Handle("/.well-known/openid-configuration", logMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, _ = w.Write(fmt.Appendf(nil, openIDConfiguration, serverConfig.port, serverConfig.port, serverConfig.port)) + _, _ = fmt.Fprintf(w, openIDConfiguration, serverConfig.port, serverConfig.port, serverConfig.port)) w.WriteHeader(200) }))) log.Info("starting auth2 server", zap.Int("port", serverConfig.port)) From 5635faca6dff3b8f73a921771e66b92e6e1f0537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:21:00 +0200 Subject: [PATCH 6/9] Manually apply suggestion --- cdc/api/middleware/middleware.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cdc/api/middleware/middleware.go b/cdc/api/middleware/middleware.go index 64004948f9..0869c1f2d0 100644 --- a/cdc/api/middleware/middleware.go +++ b/cdc/api/middleware/middleware.go @@ -153,11 +153,8 @@ func verify(ctx *gin.Context, up *upstream.Upstream) error { return errors.ErrCredentialNotFound.GenWithStackByArgs(errMsg) } - allowed := false serverCfg := config.GetGlobalServerConfig() - if slices.Contains(serverCfg.Security.ClientAllowedUser, username) { - allowed = true - } + allowed := slices.Contains(serverCfg.Security.ClientAllowedUser, username) if !allowed { errMsg := "The user is not allowed." if username == "" { From 205231898025032960863f2e9075fa307187610b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:24:03 +0200 Subject: [PATCH 7/9] Manually apply suggestion --- cdc/scheduler/internal/v3/replication/replication_set_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cdc/scheduler/internal/v3/replication/replication_set_test.go b/cdc/scheduler/internal/v3/replication/replication_set_test.go index dfc0f40d77..c71199fd7d 100644 --- a/cdc/scheduler/internal/v3/replication/replication_set_test.go +++ b/cdc/scheduler/internal/v3/replication/replication_set_test.go @@ -784,8 +784,7 @@ func TestReplicationSetRemoveTable(t *testing.T) { func clone(r *ReplicationSet) *ReplicationSet { rClone := *r - rClone.Captures = make(map[string]Role) - maps.Copy(rClone.Captures, r.Captures) + rClone.Captures = maps.Clone(r.Captures) return &rClone } From e50d63425025a3788742d3d33675028f8bc95ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:25:01 +0200 Subject: [PATCH 8/9] Manually apply suggestion --- cmd/storage-consumer/main.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/storage-consumer/main.go b/cmd/storage-consumer/main.go index 8f3ae20bf1..093fc82430 100644 --- a/cmd/storage-consumer/main.go +++ b/cmd/storage-consumer/main.go @@ -255,8 +255,7 @@ func (c *consumer) getNewFiles( tableDMLMap := make(map[cloudstorage.DmlPathKey]fileIndexRange) opt := &storeapi.WalkOption{SubDir: ""} - origDMLIdxMap := make(map[cloudstorage.DmlPathKey]uint64, len(c.tableDMLIdxMap)) - maps.Copy(origDMLIdxMap, c.tableDMLIdxMap) + origDMLIdxMap := maps.Clone(c.tableDMLIdxMap) err := c.externalStorage.WalkDir(ctx, opt, func(path string, size int64) error { if cloudstorage.IsSchemaFile(path) { From bc914b511ae4ac76de16cca22b634cbd0ebe32fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Tue, 16 Jun 2026 08:39:07 +0200 Subject: [PATCH 9/9] Use maps.Clone to simplify map copying Replace the make + maps.Copy pattern with maps.Clone where a fresh map is created and fully populated from a source map. Applies the PR review suggestions and the same simplification found elsewhere in the codebase. Co-Authored-By: Claude Opus 4.8 (1M context) --- dm/config/checking_item.go | 3 +-- dm/config/checking_item_test.go | 3 +-- dm/config/dbconfig/config.go | 5 +---- dm/pkg/shardddl/optimism/keeper.go | 3 +-- dm/pkg/shardddl/pessimism/keeper.go | 3 +-- dm/pkg/shardddl/pessimism/lock.go | 3 +-- dm/simulator/mcp/uk.go | 7 ++----- dm/syncer/sharding_group.go | 6 ++---- dm/worker/subtask_holder.go | 3 +-- pkg/p2p/grpc_client.go | 3 +-- 10 files changed, 12 insertions(+), 27 deletions(-) diff --git a/dm/config/checking_item.go b/dm/config/checking_item.go index f2821ceb16..44670cf591 100644 --- a/dm/config/checking_item.go +++ b/dm/config/checking_item.go @@ -130,8 +130,7 @@ func SupportCheckingItems() string { // FilterCheckingItems filters ignored items from all checking items. func FilterCheckingItems(ignoredItems []string) map[string]string { - checkingItems := make(map[string]string) - maps.Copy(checkingItems, AllCheckingItems) + checkingItems := maps.Clone(AllCheckingItems) delete(checkingItems, AllChecking) for _, item := range ignoredItems { diff --git a/dm/config/checking_item_test.go b/dm/config/checking_item_test.go index 2eb6dab2b8..1786b349ad 100644 --- a/dm/config/checking_item_test.go +++ b/dm/config/checking_item_test.go @@ -45,8 +45,7 @@ func TestCheckingItems(t *testing.T) { require.Empty(t, FilterCheckingItems(ignoredCheckingItems)) // ignore shard checking items - checkingItems := make(map[string]string) - maps.Copy(checkingItems, AllCheckingItems) + checkingItems := maps.Clone(AllCheckingItems) delete(checkingItems, AllChecking) require.Equal(t, checkingItems, FilterCheckingItems(ignoredCheckingItems[:0])) diff --git a/dm/config/dbconfig/config.go b/dm/config/dbconfig/config.go index 64c76ec420..bff9220d78 100644 --- a/dm/config/dbconfig/config.go +++ b/dm/config/dbconfig/config.go @@ -149,10 +149,7 @@ func (db *DBConfig) Clone() *DBConfig { clone.MaxAllowedPacket = &packet } - if db.Session != nil { - clone.Session = make(map[string]string, len(db.Session)) - maps.Copy(clone.Session, db.Session) - } + clone.Session = maps.Clone(db.Session) clone.Security = db.Security.Clone() diff --git a/dm/pkg/shardddl/optimism/keeper.go b/dm/pkg/shardddl/optimism/keeper.go index 3f9c48a42d..56f551c59d 100644 --- a/dm/pkg/shardddl/optimism/keeper.go +++ b/dm/pkg/shardddl/optimism/keeper.go @@ -165,8 +165,7 @@ func (lk *LockKeeper) Locks() map[string]*Lock { lk.mu.RLock() defer lk.mu.RUnlock() - locks := make(map[string]*Lock, len(lk.locks)) - maps.Copy(locks, lk.locks) + locks := maps.Clone(lk.locks) return locks } diff --git a/dm/pkg/shardddl/pessimism/keeper.go b/dm/pkg/shardddl/pessimism/keeper.go index f3c1a66c78..3eaf1ed9f8 100644 --- a/dm/pkg/shardddl/pessimism/keeper.go +++ b/dm/pkg/shardddl/pessimism/keeper.go @@ -85,8 +85,7 @@ func (lk *LockKeeper) Locks() map[string]*Lock { lk.mu.RLock() defer lk.mu.RUnlock() - locks := make(map[string]*Lock, len(lk.locks)) - maps.Copy(locks, lk.locks) + locks := maps.Clone(lk.locks) return locks } diff --git a/dm/pkg/shardddl/pessimism/lock.go b/dm/pkg/shardddl/pessimism/lock.go index 90a0a785a9..7f15eb1a6a 100644 --- a/dm/pkg/shardddl/pessimism/lock.go +++ b/dm/pkg/shardddl/pessimism/lock.go @@ -137,8 +137,7 @@ func (l *Lock) Ready() map[string]bool { l.mu.RLock() defer l.mu.RUnlock() - ret := make(map[string]bool, len(l.ready)) - maps.Copy(ret, l.ready) + ret := maps.Clone(l.ready) return ret } diff --git a/dm/simulator/mcp/uk.go b/dm/simulator/mcp/uk.go index ac3ba3e17e..ba90cfffca 100644 --- a/dm/simulator/mcp/uk.go +++ b/dm/simulator/mcp/uk.go @@ -67,9 +67,7 @@ func (uk *UniqueKey) SetRowID(rowID int) { func (uk *UniqueKey) GetValue() map[string]any { uk.RLock() defer uk.RUnlock() - result := make(map[string]any) - maps.Copy(result, uk.value) - return result + return maps.Clone(uk.value) } // GetValueHash return hash for values. @@ -107,9 +105,8 @@ func (uk *UniqueKey) Clone() *UniqueKey { defer uk.RUnlock() result := &UniqueKey{ rowID: uk.rowID, - value: map[string]any{}, + value: maps.Clone(uk.value), } - maps.Copy(result.value, uk.value) return result } diff --git a/dm/syncer/sharding_group.go b/dm/syncer/sharding_group.go index d1e3d794ad..0115e685c9 100644 --- a/dm/syncer/sharding_group.go +++ b/dm/syncer/sharding_group.go @@ -279,8 +279,7 @@ func (sg *ShardingGroup) UnresolvedGroupInfo() *pb.ShardingGroup { func (sg *ShardingGroup) Sources() map[string]bool { sg.RLock() defer sg.RUnlock() - ret := make(map[string]bool, len(sg.sources)) - maps.Copy(ret, sg.sources) + ret := maps.Clone(sg.sources) return ret } @@ -617,8 +616,7 @@ func (k *ShardingGroupKeeper) Groups() map[string]*ShardingGroup { defer k.RUnlock() // do a copy - groups := make(map[string]*ShardingGroup, len(k.groups)) - maps.Copy(groups, k.groups) + groups := maps.Clone(k.groups) return groups } diff --git a/dm/worker/subtask_holder.go b/dm/worker/subtask_holder.go index 7fb82aeac7..39fcedec0d 100644 --- a/dm/worker/subtask_holder.go +++ b/dm/worker/subtask_holder.go @@ -105,7 +105,6 @@ func (h *subTaskHolder) findSubTask(name string) *SubTask { func (h *subTaskHolder) getAllSubTasks() map[string]*SubTask { h.mu.RLock() defer h.mu.RUnlock() - result := make(map[string]*SubTask, len(h.subTasks)) - maps.Copy(result, h.subTasks) + result := maps.Clone(h.subTasks) return result } diff --git a/pkg/p2p/grpc_client.go b/pkg/p2p/grpc_client.go index d8d46cd5b7..8b6b91bc28 100644 --- a/pkg/p2p/grpc_client.go +++ b/pkg/p2p/grpc_client.go @@ -250,9 +250,8 @@ func (c *grpcMessageClient) runTx(ctx context.Context, stream MessageClientStrea // retrySending retries sending messages when the gRPC stream is re-established. func (c *grpcMessageClient) retrySending(ctx context.Context, stream MessageClientStream) error { - topicsCloned := make(map[string]*topicEntry) c.topicMu.RLock() - maps.Copy(topicsCloned, c.topics) + topicsCloned := maps.Clone(c.topics) c.topicMu.RUnlock() batcher := c.newSenderFn(stream)