Repository: dragonflyoss/Dragonfly2
Pull request #1701 (2022-09-23 03:01:51)

refactor: manager and scheduler config
Signed-off-by: Gaius <gaius.qi@gmail.com>

<!--- Provide a general summary of your changes in the Title above -->

## Description
- Refactor manager and scheduler config.
<!--- Describe your changes in detail -->

## Related Issue

<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->

## Screenshots (if appropriate)

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation Update (if none of the other choices apply)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [ ] I have added tests to cover my changes.


codecov-commenter: # [Codecov](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) Report
> Merging [#1701](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (26870b1) into [main](https://codecov.io/gh/dragonflyoss/Dragonfly2/commit/d6bd357e634a628618a61e2078c1d9466eac6499?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (d6bd357) will **increase** coverage by `0.18%`.
> The diff coverage is `8.33%`.

[![Impacted file tree graph](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701/graphs/tree.svg?width=650&height=150&src=pr&token=PUICJYSAT7&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)

```diff
@@            Coverage Diff             @@
##             main    #1701      +/-   ##
==========================================
+ Coverage   41.90%   42.08%   +0.18%     
==========================================
  Files         127      127              
  Lines       15671    15596      -75     
==========================================
- Hits         6567     6564       -3     
+ Misses       8587     8514      -73     
- Partials      517      518       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| Object-compatibility-e2etests | `?` | |
| e2etests | `?` | |
| unittests | `42.08% <8.33%> (+0.18%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) | Coverage Δ | |
|---|---|---|
| [manager/config/config.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-bWFuYWdlci9jb25maWcvY29uZmlnLmdv) | `0.00% <0.00%> (ø)` | |
| [scheduler/config/config.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-c2NoZWR1bGVyL2NvbmZpZy9jb25maWcuZ28=) | `0.00% <0.00%> (ø)` | |
| [scheduler/service/service.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-c2NoZWR1bGVyL3NlcnZpY2Uvc2VydmljZS5nbw==) | `77.21% <0.00%> (ø)` | |
| [scheduler/resource/resource.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-c2NoZWR1bGVyL3Jlc291cmNlL3Jlc291cmNlLmdv) | `76.74% <100.00%> (ø)` | |
| [client/daemon/rpcserver/subscriber.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9ycGNzZXJ2ZXIvc3Vic2NyaWJlci5nbw==) | `49.14% <0.00%> (-1.72%)` | :arrow_down: |


Patch:
diff --git a/cmd/manager/cmd/root.go b/cmd/manager/cmd/root.go
index 8a0bd612..df6eed72 100644
--- a/cmd/manager/cmd/root.go
+++ b/cmd/manager/cmd/root.go
@@ -58,7 +58,7 @@ for managing schedulers and seed peers, offering http apis and portal, etc.`,
 		}
 
 		// Initialize dfpath.
-		d, err := initDfpath(cfg.Server)
+		d, err := initDfpath(&cfg.Server)
 		if err != nil {
 			return err
 		}
diff --git a/cmd/scheduler/cmd/root.go b/cmd/scheduler/cmd/root.go
index b21791ef..0a0cb85d 100644
--- a/cmd/scheduler/cmd/root.go
+++ b/cmd/scheduler/cmd/root.go
@@ -62,7 +62,7 @@ generate and maintain a P2P network during the download process, and push suitab
 		defer cancel()
 
 		// Initialize dfpath.
-		d, err := initDfpath(cfg.Server)
+		d, err := initDfpath(&cfg.Server)
 		if err != nil {
 			return err
 		}
diff --git a/manager/cache/cache.go b/manager/cache/cache.go
index 8cea00ff..d5e5b1b7 100644
--- a/manager/cache/cache.go
+++ b/manager/cache/cache.go
@@ -49,11 +49,9 @@ type Cache struct {
 // New cache instance.
 func New(cfg *config.Config) (*Cache, error) {
 	var localCache *cache.TinyLFU
-	if cfg.Cache != nil {
-		localCache = cache.NewTinyLFU(cfg.Cache.Local.Size, cfg.Cache.Local.TTL)
-	}
+	localCache = cache.NewTinyLFU(cfg.Cache.Local.Size, cfg.Cache.Local.TTL)
 
-	rdb, err := database.NewRedis(cfg.Database.Redis)
+	rdb, err := database.NewRedis(&cfg.Database.Redis)
 	if err != nil {
 		return nil, err
 	}
diff --git a/manager/config/config.go b/manager/config/config.go
index 95bc97ff..29b1008b 100644
--- a/manager/config/config.go
+++ b/manager/config/config.go
@@ -35,25 +35,25 @@ type Config struct {
 	base.Options `yaml:",inline" mapstructure:",squash"`
 
 	// Server configuration.
-	Server *ServerConfig `yaml:"server" mapstructure:"server"`
+	Server ServerConfig `yaml:"server" mapstructure:"server"`
 
 	// Database configuration.
-	Database *DatabaseConfig `yaml:"database" mapstructure:"database"`
+	Database DatabaseConfig `yaml:"database" mapstructure:"database"`
 
 	// Cache configuration.
-	Cache *CacheConfig `yaml:"cache" mapstructure:"cache"`
+	Cache CacheConfig `yaml:"cache" mapstructure:"cache"`
 
 	// ObjectStorage configuration.
-	ObjectStorage *ObjectStorageConfig `yaml:"objectStorage" mapstructure:"objectStorage"`
+	ObjectStorage ObjectStorageConfig `yaml:"objectStorage" mapstructure:"objectStorage"`
 
 	// Metrics configuration.
-	Metrics *MetricsConfig `yaml:"metrics" mapstructure:"metrics"`
+	Metrics MetricsConfig `yaml:"metrics" mapstructure:"metrics"`
 
 	// Security configuration.
-	Security *SecurityConfig `yaml:"security" mapstructure:"security"`
+	Security SecurityConfig `yaml:"security" mapstructure:"security"`
 
 	// Network configuration.
-	Network *NetworkConfig `yaml:"network" mapstructure:"network"`
+	Network NetworkConfig `yaml:"network" mapstructure:"network"`
 }
 
 type ServerConfig struct {
@@ -67,10 +67,10 @@ type ServerConfig struct {
 	LogDir string `yaml:"logDir" mapstructure:"logDir"`
 
 	// GRPC server configuration.
-	GRPC *GRPCConfig `yaml:"grpc" mapstructure:"grpc"`
+	GRPC GRPCConfig `yaml:"grpc" mapstructure:"grpc"`
 
 	// REST server configuration.
-	REST *RestConfig `yaml:"rest" mapstructure:"rest"`
+	REST RestConfig `yaml:"rest" mapstructure:"rest"`
 }
 
 type DatabaseConfig struct {
@@ -78,13 +78,13 @@ type DatabaseConfig struct {
 	Type string `yaml:"type" mapstructure:"type"`
 
 	// Mysql configuration.
-	Mysql *MysqlConfig `yaml:"mysql" mapstructure:"mysql"`
+	Mysql MysqlConfig `yaml:"mysql" mapstructure:"mysql"`
 
 	// Postgres configuration.
-	Postgres *PostgresConfig `yaml:"postgres" mapstructure:"postgres"`
+	Postgres PostgresConfig `yaml:"postgres" mapstructure:"postgres"`
 
 	// Redis configuration.
-	Redis *RedisConfig `yaml:"redis" mapstructure:"redis"`
+	Redis RedisConfig `yaml:"redis" mapstructure:"redis"`
 }
 
 type MysqlConfig struct {
@@ -182,10 +182,10 @@ type RedisConfig struct {
 
 type CacheConfig struct {
 	// Redis cache configuration.
-	Redis *RedisCacheConfig `yaml:"redis" mapstructure:"redis"`
+	Redis RedisCacheConfig `yaml:"redis" mapstructure:"redis"`
 
 	// Local cache configuration.
-	Local *LocalCacheConfig `yaml:"local" mapstructure:"local"`
+	Local LocalCacheConfig `yaml:"local" mapstructure:"local"`
 }
 
 type RedisCacheConfig struct {
@@ -273,7 +273,7 @@ type SecurityConfig struct {
 	TLSPolicy string `mapstructure:"tlsPolicy" yaml:"tlsPolicy"`
 
 	// CertSpec is the desired state of certificate.
-	CertSpec *CertSpec `mapstructure:"certSpec" yaml:"certSpec"`
+	CertSpec CertSpec `mapstructure:"certSpec" yaml:"certSpec"`
 }
 
 type CertSpec struct {
@@ -295,65 +295,65 @@ type NetworkConfig struct {
 // New config instance.
 func New() *Config {
 	return &Config{
-		Server: &ServerConfig{
+		Server: ServerConfig{
 			Name: DefaultServerName,
-			GRPC: &GRPCConfig{
+			GRPC: GRPCConfig{
 				PortRange: TCPListenPortRange{
 					Start: DefaultGRPCPort,
 					End:   DefaultGRPCPort,
 				},
 			},
-			REST: &RestConfig{
+			REST: RestConfig{
 				Addr: DefaultRESTAddr,
 			},
 		},
-		Database: &DatabaseConfig{
+		Database: DatabaseConfig{
 			Type: DatabaseTypeMysql,
-			Mysql: &MysqlConfig{
+			Mysql: MysqlConfig{
 				Port:    DefaultMysqlPort,
 				DBName:  DefaultMysqlDBName,
 				Migrate: true,
 			},
-			Postgres: &PostgresConfig{
+			Postgres: PostgresConfig{
 				Port:     DefaultPostgresPort,
 				DBName:   DefaultPostgresDBName,
 				SSLMode:  DefaultPostgresSSLMode,
 				Timezone: DefaultPostgresTimezone,
 				Migrate:  true,
 			},
-			Redis: &RedisConfig{
+			Redis: RedisConfig{
 				DB:        DefaultRedisDB,
 				BrokerDB:  DefaultRedisBrokerDB,
 				BackendDB: DefaultRedisBackendDB,
 			},
 		},
-		Cache: &CacheConfig{
-			Redis: &RedisCacheConfig{
+		Cache: CacheConfig{
+			Redis: RedisCacheConfig{
 				TTL: DefaultRedisCacheTTL,
 			},
-			Local: &LocalCacheConfig{
+			Local: LocalCacheConfig{
 				Size: DefaultLFUCacheSize,
 				TTL:  DefaultLFUCacheTTL,
 			},
 		},
-		ObjectStorage: &ObjectStorageConfig{
+		ObjectStorage: ObjectStorageConfig{
 			Enable: false,
 		},
-		Security: &SecurityConfig{
+		Security: SecurityConfig{
 			AutoIssueCert: false,
 			TLSPolicy:     rpc.PreferTLSPolicy,
-			CertSpec: &CertSpec{
+			CertSpec: CertSpec{
 				IPAddresses:    DefaultCertIPAddresses,
 				DNSNames:       DefaultCertDNSNames,
 				ValidityPeriod: DefaultCertValidityPeriod,
 			},
 		},
-		Metrics: &MetricsConfig{
+		Metrics: MetricsConfig{
 			Enable:          false,
 			Addr:            DefaultMetricsAddr,
 			EnablePeerGauge: true,
 		},
-		Network: &NetworkConfig{
+		Network: NetworkConfig{
 			EnableIPv6: DefaultNetworkEnableIPv6,
 		},
 	}
@@ -361,18 +361,10 @@ func New() *Config {
 
 // Validate config values
 func (cfg *Config) Validate() error {
-	if cfg.Server == nil {
-		return errors.New("config requires parameter server")
-	}
-
 	if cfg.Server.Name == "" {
 		return errors.New("server requires parameter name")
 	}
 
-	if cfg.Server.GRPC == nil {
-		return errors.New("server requires parameter grpc")
-	}
-
 	if cfg.Server.GRPC.AdvertiseIP == "" {
 		return errors.New("grpc requires parameter advertiseIP")
 	}
@@ -381,23 +373,11 @@ func (cfg *Config) Validate() error {
 		return errors.New("grpc requires parameter listenIP")
 	}
 
-	if cfg.Server.REST == nil {
-		return errors.New("server requires parameter rest")
-	}
-
-	if cfg.Database == nil {
-		return errors.New("config requires parameter database")
-	}
-
 	if cfg.Database.Type == "" {
 		return errors.New("database requires parameter type")
 	}
 
 	if cfg.Database.Type == DatabaseTypeMysql || cfg.Database.Type == DatabaseTypeMariaDB {
-		if cfg.Database.Mysql == nil {
-			return errors.New("database requires parameter mysql")
-		}
-
 		if cfg.Database.Mysql.User == "" {
 			return errors.New("mysql requires parameter user")
 		}
@@ -434,10 +414,6 @@ func (cfg *Config) Validate() error {
 	}
 
 	if cfg.Database.Type == DatabaseTypePostgres {
-		if cfg.Database.Postgres == nil {
-			return errors.New("database requires parameter postgres")
-		}
-
 		if cfg.Database.Postgres.User == "" {
 			return errors.New("postgres requires parameter user")
 		}
@@ -467,10 +443,6 @@ func (cfg *Config) Validate() error {
 		}
 	}
 
-	if cfg.Database.Redis == nil {
-		return errors.New("database requires parameter redis")
-	}
-
 	if len(cfg.Database.Redis.Addrs) == 0 {
 		return errors.New("redis requires parameter addrs")
 	}
@@ -497,22 +469,10 @@ func (cfg *Config) Validate() error {
 		return errors.New("redis requires parameter backendDB")
 	}
 
-	if cfg.Cache == nil {
-		return errors.New("config requires parameter cache")
-	}
-
-	if cfg.Cache.Redis == nil {
-		return errors.New("cache requires parameter redis")
-	}
-
 	if cfg.Cache.Redis.TTL == 0 {
 		return errors.New("redis requires parameter ttl")
 	}
 
-	if cfg.Cache.Local == nil {
-		return errors.New("cache requires parameter local")
-	}
-
 	if cfg.Cache.Local.Size == 0 {
 		return errors.New("local requires parameter size")
 	}
@@ -521,11 +481,7 @@ func (cfg *Config) Validate() error {
 		return errors.New("local requires parameter ttl")
 	}
 
-	if cfg.ObjectStorage == nil {
-		return errors.New("config requires parameter objectStorage")
-	}
-
-	if cfg.ObjectStorage != nil && cfg.ObjectStorage.Enable {
+	if cfg.ObjectStorage.Enable {
 		if cfg.ObjectStorage.Name == "" {
 			return errors.New("objectStorage requires parameter name")
 		}
@@ -543,10 +499,6 @@ func (cfg *Config) Validate() error {
 		}
 	}
 
-	if cfg.Security == nil {
-		return errors.New("config requires parameter security")
-	}
-
 	if cfg.Security.AutoIssueCert {
 		if cfg.Security.CACert == "" {
 			return errors.New("security requires parameter caCert")
@@ -560,10 +512,6 @@ func (cfg *Config) Validate() error {
 			return errors.New("security requires parameter tlsPolicy")
 		}
 
-		if cfg.Security.CertSpec == nil {
-			return errors.New("security requires parameter certSpec")
-		}
-
 		if len(cfg.Security.CertSpec.IPAddresses) == 0 {
 			return errors.New("certSpec requires parameter ipAddresses")
 		}
@@ -573,20 +521,12 @@ func (cfg *Config) Validate() error {
 		}
 	}
 
-	if cfg.Metrics == nil {
-		return errors.New("config requires parameter metrics")
-	}
-
 	if cfg.Metrics.Enable {
 		if cfg.Metrics.Addr == "" {
 			return errors.New("metrics requires parameter addr")
 		}
 	}
 
-	if cfg.Network == nil {
-		return errors.New("config requires parameter network")
-	}
-
 	return nil
 }
 
diff --git a/manager/database/database.go b/manager/database/database.go
index f6110e21..e9208313 100644
--- a/manager/database/database.go
+++ b/manager/database/database.go
@@ -60,7 +60,7 @@ func New(cfg *config.Config) (*Database, error) {
 		return nil, fmt.Errorf("invalid database type %s", cfg.Database.Type)
 	}
 
-	rdb, err := NewRedis(cfg.Database.Redis)
+	rdb, err := NewRedis(&cfg.Database.Redis)
 	if err != nil {
 		return nil, err
 	}
diff --git a/manager/database/mysql.go b/manager/database/mysql.go
index 91e286af..ec948a9b 100644
--- a/manager/database/mysql.go
+++ b/manager/database/mysql.go
@@ -32,10 +32,10 @@ import (
 )
 
 func newMyqsl(cfg *config.Config) (*gorm.DB, error) {
-	m := cfg.Database.Mysql
+	mysqlCfg := &cfg.Database.Mysql
 
 	// Format dsn string.
-	dsn, err := formatMysqlDSN(m)
+	dsn, err := formatMysqlDSN(mysqlCfg)
 	if err != nil {
 		return nil, err
 	}
@@ -53,7 +53,7 @@ func newMyqsl(cfg *config.Config) (*gorm.DB, error) {
 	}
 
 	// Run migration.
-	if m.Migrate {
+	if mysqlCfg.Migrate {
 		if err := migrate(db); err != nil {
 			return nil, err
 		}
diff --git a/manager/database/postgres.go b/manager/database/postgres.go
index 85dd687b..d3ed2bc8 100644
--- a/manager/database/postgres.go
+++ b/manager/database/postgres.go
@@ -29,10 +29,10 @@ import (
 )
 
 func newPostgres(cfg *config.Config) (*gorm.DB, error) {
-	p := cfg.Database.Postgres
+	postgresCfg := &cfg.Database.Postgres
 
 	// Format dsn string.
-	dsn := formatPostgresDSN(p)
+	dsn := formatPostgresDSN(postgresCfg)
 
 	// Connect to mysql.
 	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
@@ -47,7 +47,7 @@ func newPostgres(cfg *config.Config) (*gorm.DB, error) {
 	}
 
 	// Run migration.
-	if p.Migrate {
+	if postgresCfg.Migrate {
 		if err := migrate(db); err != nil {
 			return nil, err
 		}
diff --git a/manager/manager.go b/manager/manager.go
index 1fb454c1..1e957ad9 100644
--- a/manager/manager.go
+++ b/manager/manager.go
@@ -210,7 +210,7 @@ func New(cfg *config.Config, d dfpath.Dfpath) (*Server, error) {
 	}
 
 	// Initialize GRPC server
-	_, grpcServer, err := rpcserver.New(cfg, db, cache, searcher, objectStorage, cfg.ObjectStorage, options...)
+	_, grpcServer, err := rpcserver.New(cfg, db, cache, searcher, objectStorage, &cfg.ObjectStorage, options...)
 	if err != nil {
 		return nil, err
 	}
@@ -219,7 +219,7 @@ func New(cfg *config.Config, d dfpath.Dfpath) (*Server, error) {
 
 	// Initialize prometheus
 	if cfg.Metrics.Enable {
-		s.metricsServer = metrics.New(cfg.Metrics, grpcServer)
+		s.metricsServer = metrics.New(&cfg.Metrics, grpcServer)
 	}
 
 	return s, nil
diff --git a/scheduler/config/config.go b/scheduler/config/config.go
index c43c7687..624451a9 100644
--- a/scheduler/config/config.go
+++ b/scheduler/config/config.go
@@ -35,37 +35,37 @@ type Config struct {
 	base.Options `yaml:",inline" mapstructure:",squash"`
 
 	// Scheduler configuration.
-	Scheduler *SchedulerConfig `yaml:"scheduler" mapstructure:"scheduler"`
+	Scheduler SchedulerConfig `yaml:"scheduler" mapstructure:"scheduler"`
 
 	// Server configuration.
-	Server *ServerConfig `yaml:"server" mapstructure:"server"`
+	Server ServerConfig `yaml:"server" mapstructure:"server"`
 
 	// Dynconfig configuration.
-	DynConfig *DynConfig `yaml:"dynConfig" mapstructure:"dynConfig"`
+	DynConfig DynConfig `yaml:"dynConfig" mapstructure:"dynConfig"`
 
 	// Manager configuration.
-	Manager *ManagerConfig `yaml:"manager" mapstructure:"manager"`
+	Manager ManagerConfig `yaml:"manager" mapstructure:"manager"`
 
 	// SeedPeer configuration.
-	SeedPeer *SeedPeerConfig `yaml:"seedPeer" mapstructure:"seedPeer"`
+	SeedPeer SeedPeerConfig `yaml:"seedPeer" mapstructure:"seedPeer"`
 
 	// Host configuration.
-	Host *HostConfig `yaml:"host" mapstructure:"host"`
+	Host HostConfig `yaml:"host" mapstructure:"host"`
 
 	// Job configuration.
-	Job *JobConfig `yaml:"job" mapstructure:"job"`
+	Job JobConfig `yaml:"job" mapstructure:"job"`
 
 	// Storage configuration.
-	Storage *StorageConfig `yaml:"storage" mapstructure:"storage"`
+	Storage StorageConfig `yaml:"storage" mapstructure:"storage"`
 
 	// Metrics configuration.
-	Metrics *MetricsConfig `yaml:"metrics" mapstructure:"metrics"`
+	Metrics MetricsConfig `yaml:"metrics" mapstructure:"metrics"`
 
 	// Security configuration.
-	Security *SecurityConfig `yaml:"security" mapstructure:"security"`
+	Security SecurityConfig `yaml:"security" mapstructure:"security"`
 
 	// Network configuration.
-	Network *NetworkConfig `yaml:"network" mapstructure:"network"`
+	Network NetworkConfig `yaml:"network" mapstructure:"network"`
 }
 
 type ServerConfig struct {
@@ -117,10 +117,10 @@ type SchedulerConfig struct {
 	RetryInterval time.Duration `yaml:"retryInterval" mapstructure:"retryInterval"`
 
 	// Task and peer gc configuration.
-	GC *GCConfig `yaml:"gc" mapstructure:"gc"`
+	GC GCConfig `yaml:"gc" mapstructure:"gc"`
 
 	// Training configuration.
-	Training *TrainingConfig `yaml:"training" mapstructure:"training"`
+	Training TrainingConfig `yaml:"training" mapstructure:"training"`
 }
 
 type TrainingConfig struct {
@@ -208,7 +208,7 @@ type JobConfig struct {
 	LocalWorkerNum uint `yaml:"localWorkerNum" mapstructure:"localWorkerNum"`
 
 	// Redis configuration.
-	Redis *RedisConfig `yaml:"redis" mapstructure:"redis"`
+	Redis RedisConfig `yaml:"redis" mapstructure:"redis"`
 }
 
 type StorageConfig struct {
@@ -275,7 +275,7 @@ type SecurityConfig struct {
 	TLSPolicy string `mapstructure:"tlsPolicy" yaml:"tlsPolicy"`
 
 	// CertSpec is the desired state of certificate.
-	CertSpec *CertSpec `mapstructure:"certSpec" yaml:"certSpec"`
+	CertSpec CertSpec `mapstructure:"certSpec" yaml:"certSpec"`
 }
 
 type CertSpec struct {
@@ -291,17 +291,17 @@ type NetworkConfig struct {
 // New default configuration.
 func New() *Config {
 	return &Config{
-		Server: &ServerConfig{
+		Server: ServerConfig{
 			Port: DefaultServerPort,
 			Host: fqdn.FQDNHostname,
 		},
-		Scheduler: &SchedulerConfig{
+		Scheduler: SchedulerConfig{
 			Algorithm:            DefaultSchedulerAlgorithm,
 			BackSourceCount:      DefaultSchedulerBackSourceCount,
 			RetryBackSourceLimit: DefaultSchedulerRetryBackSourceLimit,
 			RetryLimit:           DefaultSchedulerRetryLimit,
 			RetryInterval:        DefaultSchedulerRetryInterval,
-			GC: &GCConfig{
+			GC: GCConfig{
 				PeerGCInterval: DefaultSchedulerPeerGCInterval,
 				PeerTTL:        DefaultSchedulerPeerTTL,
 				TaskGCInterval: DefaultSchedulerTaskGCInterval,
@@ -309,55 +309,55 @@ func New() *Config {
 				HostGCInterval: DefaultSchedulerHostGCInterval,
 				HostTTL:        DefaultSchedulerHostTTL,
 			},
-			Training: &TrainingConfig{
+			Training: TrainingConfig{
 				Enable:               false,
 				EnableAutoRefresh:    false,
 				RefreshModelInterval: DefaultRefreshModelInterval,
 				CPU:                  DefaultCPU,
 			},
 		},
-		DynConfig: &DynConfig{
+		DynConfig: DynConfig{
 			RefreshInterval: DefaultDynConfigRefreshInterval,
 		},
-		Host: &HostConfig{},
-		Manager: &ManagerConfig{
+		Host: HostConfig{},
+		Manager: ManagerConfig{
 			SchedulerClusterID: DefaultManagerSchedulerClusterID,
 			KeepAlive: KeepAliveConfig{
 				Interval: DefaultManagerKeepAliveInterval,
 			},
 		},
-		SeedPeer: &SeedPeerConfig{
+		SeedPeer: SeedPeerConfig{
 			Enable: true,
 		},
-		Job: &JobConfig{
+		Job: JobConfig{
 			Enable:             true,
 			GlobalWorkerNum:    DefaultJobGlobalWorkerNum,
 			SchedulerWorkerNum: DefaultJobSchedulerWorkerNum,
 			LocalWorkerNum:     DefaultJobLocalWorkerNum,
-			Redis: &RedisConfig{
+			Redis: RedisConfig{
 				BrokerDB:  DefaultJobRedisBrokerDB,
 				BackendDB: DefaultJobRedisBackendDB,
 			},
 		},
-		Storage: &StorageConfig{
+		Storage: StorageConfig{
 			MaxSize:    storage.DefaultMaxSize,
 			MaxBackups: storage.DefaultMaxBackups,
 			BufferSize: storage.DefaultBufferSize,
 		},
-		Metrics: &MetricsConfig{
+		Metrics: MetricsConfig{
 			Enable:         false,
 			Addr:           DefaultMetricsAddr,
 			EnablePeerHost: false,
 		},
-		Security: &SecurityConfig{
+		Security: SecurityConfig{
 			AutoIssueCert: false,
 			TLSVerify:     true,
 			TLSPolicy:     rpc.PreferTLSPolicy,
-			CertSpec: &CertSpec{
+			CertSpec: CertSpec{
 				ValidityPeriod: DefaultCertValidityPeriod,
 			},
 		},
-		Network: &NetworkConfig{
+		Network: NetworkConfig{
 			EnableIPv6: DefaultNetworkEnableIPv6,
 		},
 	}
@@ -365,10 +365,6 @@ func New() *Config {
 
 // Validate config parameters.
 func (cfg *Config) Validate() error {
-	if cfg.Server == nil {
-		return errors.New("config requires parameter server")
-	}
-
 	if cfg.Server.AdvertiseIP == "" {
 		return errors.New("server requires parameter advertiseIP")
 	}
@@ -385,10 +381,6 @@ func (cfg *Config) Validate() error {
 		return errors.New("server requires parameter host")
 	}
 
-	if cfg.Scheduler == nil {
-		return errors.New("config requires parameter scheduler")
-	}
-
 	if cfg.Scheduler.Algorithm == "" {
 		return errors.New("scheduler requires parameter algorithm")
 	}
@@ -401,10 +393,6 @@ func (cfg *Config) Validate() error {
 		return errors.New("scheduler requires parameter retryInterval")
 	}
 
-	if cfg.Scheduler.GC == nil {
-		return errors.New("scheduler requires parameter gc")
-	}
-
 	if cfg.Scheduler.GC.PeerGCInterval <= 0 {
 		return errors.New("scheduler requires parameter peerGCInterval")
 	}
@@ -421,7 +409,7 @@ func (cfg *Config) Validate() error {
 		return errors.New("scheduler requires parameter taskTTL")
 	}
 
-	if cfg.Scheduler.Training != nil && cfg.Scheduler.Training.Enable {
+	if cfg.Scheduler.Training.Enable {
 		if cfg.Scheduler.Training.CPU <= 0 {
 			return errors.New("training requires parameter cpu")
 		}
@@ -431,18 +419,10 @@ func (cfg *Config) Validate() error {
 		}
 	}
 
-	if cfg.DynConfig == nil {
-		return errors.New("config requires parameter dynConfig")
-	}
-
 	if cfg.DynConfig.RefreshInterval <= 0 {
 		return errors.New("dynconfig requires parameter refreshInterval")
 	}
 
-	if cfg.Manager == nil {
-		return errors.New("manager requires parameter dynConfig")
-	}
-
 	if cfg.Manager.Addr == "" {
 		return errors.New("manager requires parameter addr")
 	}
@@ -455,10 +435,6 @@ func (cfg *Config) Validate() error {
 		return errors.New("manager requires parameter keepAlive interval")
 	}
 
-	if cfg.Job == nil {
-		return errors.New("config requires parameter job")
-	}
-
 	if cfg.Job.Enable {
 		if cfg.Job.GlobalWorkerNum == 0 {
 			return errors.New("job requires parameter globalWorkerNum")
@@ -487,10 +463,6 @@ func (cfg *Config) Validate() error {
 		}
 	}
 
-	if cfg.Storage == nil {
-		return errors.New("config requires parameter storage")
-	}
-
 	if cfg.Storage.MaxSize <= 0 {
 		return errors.New("storage requires parameter maxSize")
 	}
@@ -503,10 +475,6 @@ func (cfg *Config) Validate() error {
 		return errors.New("storage requires parameter bufferSize")
 	}
 
-	if cfg.Metrics == nil {
-		return errors.New("config requires parameter metrics")
-	}
-
 	if cfg.Metrics.Enable {
 		if cfg.Metrics.Addr == "" {
 			return errors.New("metrics requires parameter addr")
@@ -518,19 +486,11 @@ func (cfg *Config) Validate() error {
 			return errors.New("security requires parameter caCert")
 		}
 
-		if cfg.Security.CertSpec == nil {
-			return errors.New("security requires parameter certSpec")
-		}
-
 		if cfg.Security.CertSpec.ValidityPeriod <= 0 {
 			return errors.New("certSpec requires parameter validityPeriod")
 		}
 	}
 
-	if cfg.Network == nil {
-		return errors.New("config requires parameter network")
-	}
-
 	return nil
 }
 
diff --git a/scheduler/resource/resource.go b/scheduler/resource/resource.go
index 2af096fd..5a8fc226 100644
--- a/scheduler/resource/resource.go
+++ b/scheduler/resource/resource.go
@@ -63,21 +63,21 @@ func New(cfg *config.Config, gc gc.GC, dynconfig config.DynconfigInterface, opts
 	resource := &resource{}
 
 	// Initialize host manager interface.
-	hostManager, err := newHostManager(cfg.Scheduler.GC, gc)
+	hostManager, err := newHostManager(&cfg.Scheduler.GC, gc)
 	if err != nil {
 		return nil, err
 	}
 	resource.hostManager = hostManager
 
 	// Initialize task manager interface.
-	taskManager, err := newTaskManager(cfg.Scheduler.GC, gc)
+	taskManager, err := newTaskManager(&cfg.Scheduler.GC, gc)
 	if err != nil {
 		return nil, err
 	}
 	resource.taskManager = taskManager
 
 	// Initialize peer manager interface.
-	peerManager, err := newPeerManager(cfg.Scheduler.GC, gc)
+	peerManager, err := newPeerManager(&cfg.Scheduler.GC, gc)
 	if err != nil {
 		return nil, err
 	}
diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go
index 6c173dc1..ca2b35ae 100644
--- a/scheduler/scheduler.go
+++ b/scheduler/scheduler.go
@@ -176,7 +176,7 @@ func New(ctx context.Context, cfg *config.Config, d dfpath.Dfpath) (*Server, err
 	}
 
 	// Initialize scheduler.
-	scheduler := scheduler.New(cfg.Scheduler, dynconfig, d.PluginDir())
+	scheduler := scheduler.New(&cfg.Scheduler, dynconfig, d.PluginDir())
 
 	// Initialize Storage.
 	storage, err := storage.New(d.DataDir())
@@ -214,7 +214,7 @@ func New(ctx context.Context, cfg *config.Config, d dfpath.Dfpath) (*Server, err
 
 	// Initialize metrics.
 	if cfg.Metrics.Enable {
-		s.metricsServer = metrics.New(cfg.Metrics, s.grpcServer)
+		s.metricsServer = metrics.New(&cfg.Metrics, s.grpcServer)
 	}
 
 	return s, nil
diff --git a/scheduler/service/service.go b/scheduler/service/service.go
index 52a9db14..d1c77e5b 100644
--- a/scheduler/service/service.go
+++ b/scheduler/service/service.go
@@ -337,7 +337,7 @@ func (s *Service) ReportPieceResult(stream schedulerv1.Scheduler_ReportPieceResu
 			s.handlePieceSuccess(ctx, peer, piece)
 
 			// Collect peer host traffic metrics.
-			if s.config.Metrics != nil && s.config.Metrics.EnablePeerHost {
+			if s.config.Metrics.Enable && s.config.Metrics.EnablePeerHost {
 				metrics.PeerHostTraffic.WithLabelValues(peer.Tag, peer.Application, metrics.PeerHostTrafficDownloadType, peer.Host.ID, peer.Host.IP).Add(float64(piece.PieceInfo.RangeSize))
 				if parent, ok := s.resource.PeerManager().Load(piece.DstPid); ok {
 					metrics.PeerHostTraffic.WithLabelValues(peer.Tag, peer.Application, metrics.PeerHostTrafficUploadType, parent.Host.ID, parent.Host.IP).Add(float64(piece.PieceInfo.RangeSize))


Test patch:
diff --git a/manager/config/config_test.go b/manager/config/config_test.go
index 02327887..2670284b 100644
--- a/manager/config/config_test.go
+++ b/manager/config/config_test.go
@@ -31,11 +31,11 @@ func TestManagerConfig_Load(t *testing.T) {
 	assert := testifyassert.New(t)
 
 	config := &Config{
-		Server: &ServerConfig{
+		Server: ServerConfig{
 			Name:     "foo",
 			CacheDir: "foo",
 			LogDir:   "foo",
-			GRPC: &GRPCConfig{
+			GRPC: GRPCConfig{
 				AdvertiseIP: "127.0.0.1",
 				ListenIP:    "0.0.0.0",
 				PortRange: TCPListenPortRange{
@@ -43,13 +43,13 @@ func TestManagerConfig_Load(t *testing.T) {
 					End:   65003,
 				},
 			},
-			REST: &RestConfig{
+			REST: RestConfig{
 				Addr: ":8080",
 			},
 		},
-		Database: &DatabaseConfig{
+		Database: DatabaseConfig{
 			Type: "mysql",
-			Mysql: &MysqlConfig{
+			Mysql: MysqlConfig{
 				User:      "foo",
 				Password:  "foo",
 				Host:      "foo",
@@ -64,7 +64,7 @@ func TestManagerConfig_Load(t *testing.T) {
 				},
 				Migrate: true,
 			},
-			Postgres: &PostgresConfig{
+			Postgres: PostgresConfig{
 				User:     "foo",
 				Password: "foo",
 				Host:     "foo",
@@ -74,7 +74,7 @@ func TestManagerConfig_Load(t *testing.T) {
 				Timezone: "UTC",
 				Migrate:  true,
 			},
-			Redis: &RedisConfig{
+			Redis: RedisConfig{
 				Host:      "bar",
 				Password:  "bar",
 				Addrs:     []string{"foo", "bar"},
@@ -84,16 +84,16 @@ func TestManagerConfig_Load(t *testing.T) {
 				BackendDB: 2,
 			},
 		},
-		Cache: &CacheConfig{
-			Redis: &RedisCacheConfig{
+		Cache: CacheConfig{
+			Redis: RedisCacheConfig{
 				TTL: 1000,
 			},
-			Local: &LocalCacheConfig{
+			Local: LocalCacheConfig{
 				Size: 10000,
 				TTL:  1000,
 			},
 		},
-		ObjectStorage: &ObjectStorageConfig{
+		ObjectStorage: ObjectStorageConfig{
 			Enable:    true,
 			Name:      objectstorage.ServiceNameS3,
 			Endpoint:  "127.0.0.1",
@@ -101,23 +101,23 @@ func TestManagerConfig_Load(t *testing.T) {
 			SecretKey: "bar",
 			Region:    "baz",
 		},
-		Security: &SecurityConfig{
+		Security: SecurityConfig{
 			AutoIssueCert: true,
 			CACert:        "foo",
 			CAKey:         "bar",
 			TLSPolicy:     "force",
-			CertSpec: &CertSpec{
+			CertSpec: CertSpec{
 				IPAddresses:    []string{"127.0.0.1"},
 				DNSNames:       []string{"foo"},
 				ValidityPeriod: 1000,
 			},
 		},
-		Metrics: &MetricsConfig{
+		Metrics: MetricsConfig{
 			Enable:          true,
 			Addr:            ":8000",
 			EnablePeerGauge: false,
 		},
-		Network: &NetworkConfig{
+		Network: NetworkConfig{
 			EnableIPv6: true,
 		},
 	}
diff --git a/scheduler/config/config_test.go b/scheduler/config/config_test.go
index 112b4db5..7124711a 100644
--- a/scheduler/config/config_test.go
+++ b/scheduler/config/config_test.go
@@ -30,13 +30,13 @@ func TestConfig_Load(t *testing.T) {
 	assert := testifyassert.New(t)
 
 	config := &Config{
-		Scheduler: &SchedulerConfig{
+		Scheduler: SchedulerConfig{
 			Algorithm:            "default",
 			BackSourceCount:      3,
 			RetryBackSourceLimit: 2,
 			RetryLimit:           10,
 			RetryInterval:        1 * time.Second,
-			GC: &GCConfig{
+			GC: GCConfig{
 				PeerGCInterval: 1 * time.Minute,
 				PeerTTL:        5 * time.Minute,
 				TaskGCInterval: 1 * time.Minute,
@@ -44,14 +44,14 @@ func TestConfig_Load(t *testing.T) {
 				HostGCInterval: 1 * time.Minute,
 				HostTTL:        10 * time.Minute,
 			},
-			Training: &TrainingConfig{
+			Training: TrainingConfig{
 				Enable:               true,
 				EnableAutoRefresh:    true,
 				RefreshModelInterval: 1 * time.Second,
 				CPU:                  2,
 			},
 		},
-		Server: &ServerConfig{
+		Server: ServerConfig{
 			AdvertiseIP: "127.0.0.1",
 			ListenIP:    "0.0.0.0",
 			Port:        8002,
@@ -61,30 +61,30 @@ func TestConfig_Load(t *testing.T) {
 			LogDir:      "bar",
 			DataDir:     "baz",
 		},
-		DynConfig: &DynConfig{
+		DynConfig: DynConfig{
 			RefreshInterval: 5 * time.Minute,
 		},
-		Manager: &ManagerConfig{
+		Manager: ManagerConfig{
 			Addr:               "127.0.0.1:65003",
 			SchedulerClusterID: 1,
 			KeepAlive: KeepAliveConfig{
 				Interval: 5 * time.Second,
 			},
 		},
-		SeedPeer: &SeedPeerConfig{
+		SeedPeer: SeedPeerConfig{
 			Enable: true,
 		},
-		Host: &HostConfig{
+		Host: HostConfig{
 			IDC:         "foo",
 			NetTopology: "bar",
 			Location:    "baz",
 		},
-		Job: &JobConfig{
+		Job: JobConfig{
 			Enable:             true,
 			GlobalWorkerNum:    1,
 			SchedulerWorkerNum: 1,
 			LocalWorkerNum:     5,
-			Redis: &RedisConfig{
+			Redis: RedisConfig{
 				Addrs:     []string{"foo", "bar"},
 				Host:      "127.0.0.1",
 				Port:      6379,
@@ -93,26 +93,26 @@ func TestConfig_Load(t *testing.T) {
 				BackendDB: 2,
 			},
 		},
-		Storage: &StorageConfig{
+		Storage: StorageConfig{
 			MaxSize:    1,
 			MaxBackups: 1,
 			BufferSize: 1,
 		},
-		Metrics: &MetricsConfig{
+		Metrics: MetricsConfig{
 			Enable:         false,
 			Addr:           ":8000",
 			EnablePeerHost: false,
 		},
-		Security: &SecurityConfig{
+		Security: SecurityConfig{
 			AutoIssueCert: true,
 			CACert:        "foo",
 			TLSVerify:     true,
 			TLSPolicy:     "force",
-			CertSpec: &CertSpec{
+			CertSpec: CertSpec{
 				ValidityPeriod: 1000,
 			},
 		},
-		Network: &NetworkConfig{
+		Network: NetworkConfig{
 			EnableIPv6: true,
 		},
 	}
diff --git a/scheduler/config/dynconfig_test.go b/scheduler/config/dynconfig_test.go
index 11e977c1..7d16b1d3 100644
--- a/scheduler/config/dynconfig_test.go
+++ b/scheduler/config/dynconfig_test.go
@@ -35,11 +35,11 @@ import (
 func TestDynconfig_GetManagerSourceType(t *testing.T) {
 	mockCacheDir := t.TempDir()
 	mockConfig := &Config{
-		DynConfig: &DynConfig{},
-		Server: &ServerConfig{
+		DynConfig: DynConfig{},
+		Server: ServerConfig{
 			Host: "localhost",
 		},
-		Manager: &ManagerConfig{
+		Manager: ManagerConfig{
 			SchedulerClusterID: 1,
 		},
 	}
diff --git a/scheduler/resource/resource_test.go b/scheduler/resource/resource_test.go
index 09aedc6f..fb7359ea 100644
--- a/scheduler/resource/resource_test.go
+++ b/scheduler/resource/resource_test.go
@@ -136,8 +136,8 @@ func TestResource_New(t *testing.T) {
 		{
 			name: "new resource without seed peer",
 			config: &config.Config{
-				Scheduler: &config.SchedulerConfig{
-					GC: &config.GCConfig{
+				Scheduler: config.SchedulerConfig{
+					GC: config.GCConfig{
 						PeerGCInterval: 100,
 						PeerTTL:        1000,
 						TaskGCInterval: 100,
@@ -146,7 +146,7 @@ func TestResource_New(t *testing.T) {
 						HostTTL:        1000,
 					},
 				},
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: false,
 				},
 			},
diff --git a/scheduler/rpcserver/rpcserver_test.go b/scheduler/rpcserver/rpcserver_test.go
index 18bf62cf..178edfa7 100644
--- a/scheduler/rpcserver/rpcserver_test.go
+++ b/scheduler/rpcserver/rpcserver_test.go
@@ -33,7 +33,7 @@ import (
 )
 
 var (
-	mockSchedulerConfig = &config.SchedulerConfig{
+	mockSchedulerConfig = config.SchedulerConfig{
 		RetryLimit:           10,
 		RetryBackSourceLimit: 3,
 		RetryInterval:        10 * time.Millisecond,
diff --git a/scheduler/service/service_test.go b/scheduler/service/service_test.go
index 05679d9e..e00db69d 100644
--- a/scheduler/service/service_test.go
+++ b/scheduler/service/service_test.go
@@ -54,7 +54,7 @@ import (
 )
 
 var (
-	mockSchedulerConfig = &config.SchedulerConfig{
+	mockSchedulerConfig = config.SchedulerConfig{
 		RetryLimit:           10,
 		RetryBackSourceLimit: 3,
 		RetryInterval:        10 * time.Millisecond,
@@ -1285,7 +1285,7 @@ func TestService_StatTask(t *testing.T) {
 			dynconfig := configmocks.NewMockDynconfigInterface(ctl)
 			storage := storagemocks.NewMockStorage(ctl)
 			taskManager := resource.NewMockTaskManager(ctl)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 			mockTask := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 
 			tc.mock(mockTask, taskManager, res.EXPECT(), taskManager.EXPECT())
@@ -1525,7 +1525,7 @@ func TestService_AnnounceTask(t *testing.T) {
 			hostManager := resource.NewMockHostManager(ctl)
 			taskManager := resource.NewMockTaskManager(ctl)
 			peerManager := resource.NewMockPeerManager(ctl)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 			mockHost := resource.NewHost(mockRawHost)
 			mockTask := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 			mockPeer := resource.NewPeer(mockPeerID, mockTask, mockHost)
@@ -1766,7 +1766,7 @@ func TestService_LeaveTask(t *testing.T) {
 			mockTask := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 			peer := resource.NewPeer(mockSeedPeerID, mockTask, mockHost)
 			child := resource.NewPeer(mockPeerID, mockTask, mockHost)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 
 			tc.mock(peer, child, peerManager, scheduler.EXPECT(), res.EXPECT(), peerManager.EXPECT())
 			tc.expect(t, peer, svc.LeaveTask(context.Background(), &schedulerv1.PeerTarget{}))
@@ -1785,7 +1785,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task already exists and state is TaskStatePending",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -1813,7 +1813,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task already exists and state is TaskStateRunning",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -1841,7 +1841,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task already exists and state is TaskStateSucceeded",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -1869,7 +1869,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStatePending",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -1906,7 +1906,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStateFailed",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -1943,7 +1943,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStateFailed and host type is HostTypeSuperSeed",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -1975,7 +1975,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStatePending, but trigger seedPeer failed",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -2012,7 +2012,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStateFailed, but trigger seedPeer failed",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: true,
 				},
 			},
@@ -2049,7 +2049,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStatePending and disable seed peer",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: false,
 				},
 			},
@@ -2080,7 +2080,7 @@ func TestService_registerTask(t *testing.T) {
 			name: "task state is TaskStateFailed and disable seed peer",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer: &config.SeedPeerConfig{
+				SeedPeer: config.SeedPeerConfig{
 					Enable: false,
 				},
 			},
@@ -2498,7 +2498,7 @@ func TestService_handlePieceSuccess(t *testing.T) {
 			res := resource.NewMockResource(ctl)
 			dynconfig := configmocks.NewMockDynconfigInterface(ctl)
 			storage := storagemocks.NewMockStorage(ctl)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 
 			tc.mock(tc.peer)
 			svc.handlePieceSuccess(context.Background(), tc.peer, tc.piece)
@@ -2523,8 +2523,8 @@ func TestService_handlePieceFail(t *testing.T) {
 			name: "peer state is PeerStateBackToSource",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer:  &config.SeedPeerConfig{Enable: true},
-				Metrics:   &config.MetricsConfig{EnablePeerHost: true},
+				SeedPeer:  config.SeedPeerConfig{Enable: true},
+				Metrics:   config.MetricsConfig{EnablePeerHost: true},
 			},
 			piece:  &schedulerv1.PieceResult{},
 			peer:   resource.NewPeer(mockPeerID, mockTask, mockHost),
@@ -2541,8 +2541,8 @@ func TestService_handlePieceFail(t *testing.T) {
 			name: "can not found parent",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer:  &config.SeedPeerConfig{Enable: true},
-				Metrics:   &config.MetricsConfig{EnablePeerHost: true},
+				SeedPeer:  config.SeedPeerConfig{Enable: true},
+				Metrics:   config.MetricsConfig{EnablePeerHost: true},
 			},
 			piece: &schedulerv1.PieceResult{
 				Code:   commonv1.Code_ClientWaitPieceReady,
@@ -2569,8 +2569,8 @@ func TestService_handlePieceFail(t *testing.T) {
 			name: "piece result code is Code_PeerTaskNotFound and parent state set PeerEventDownloadFailed",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer:  &config.SeedPeerConfig{Enable: true},
-				Metrics:   &config.MetricsConfig{EnablePeerHost: true},
+				SeedPeer:  config.SeedPeerConfig{Enable: true},
+				Metrics:   config.MetricsConfig{EnablePeerHost: true},
 			},
 			piece: &schedulerv1.PieceResult{
 				Code:   commonv1.Code_PeerTaskNotFound,
@@ -2599,8 +2599,8 @@ func TestService_handlePieceFail(t *testing.T) {
 			name: "piece result code is Code_ClientPieceNotFound and parent is not seed peer",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer:  &config.SeedPeerConfig{Enable: true},
-				Metrics:   &config.MetricsConfig{EnablePeerHost: true},
+				SeedPeer:  config.SeedPeerConfig{Enable: true},
+				Metrics:   config.MetricsConfig{EnablePeerHost: true},
 			},
 			piece: &schedulerv1.PieceResult{
 				Code:   commonv1.Code_ClientPieceNotFound,
@@ -2628,8 +2628,8 @@ func TestService_handlePieceFail(t *testing.T) {
 			name: "piece result code is Code_ClientPieceRequestFail",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer:  &config.SeedPeerConfig{Enable: true},
-				Metrics:   &config.MetricsConfig{EnablePeerHost: true},
+				SeedPeer:  config.SeedPeerConfig{Enable: true},
+				Metrics:   config.MetricsConfig{EnablePeerHost: true},
 			},
 			piece: &schedulerv1.PieceResult{
 				Code:   commonv1.Code_ClientPieceRequestFail,
@@ -2658,8 +2658,8 @@ func TestService_handlePieceFail(t *testing.T) {
 			name: "piece result code is unknow",
 			config: &config.Config{
 				Scheduler: mockSchedulerConfig,
-				SeedPeer:  &config.SeedPeerConfig{Enable: true},
-				Metrics:   &config.MetricsConfig{EnablePeerHost: true},
+				SeedPeer:  config.SeedPeerConfig{Enable: true},
+				Metrics:   config.MetricsConfig{EnablePeerHost: true},
 			},
 			piece: &schedulerv1.PieceResult{
 				Code:   commonv1.Code_ClientPieceRequestFail,
@@ -2812,7 +2812,7 @@ func TestService_handlePeerSuccess(t *testing.T) {
 			mockHost := resource.NewHost(mockRawHost)
 			mockTask := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 			peer := resource.NewPeer(mockPeerID, mockTask, mockHost)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 
 			tc.mock(peer)
 			svc.handlePeerSuccess(context.Background(), peer)
@@ -2887,7 +2887,7 @@ func TestService_handlePeerFail(t *testing.T) {
 			res := resource.NewMockResource(ctl)
 			dynconfig := configmocks.NewMockDynconfigInterface(ctl)
 			storage := storagemocks.NewMockStorage(ctl)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 			mockHost := resource.NewHost(mockRawHost)
 			mockTask := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 			peer := resource.NewPeer(mockSeedPeerID, mockTask, mockHost)
@@ -2971,7 +2971,7 @@ func TestService_handleTaskSuccess(t *testing.T) {
 			res := resource.NewMockResource(ctl)
 			dynconfig := configmocks.NewMockDynconfigInterface(ctl)
 			storage := storagemocks.NewMockStorage(ctl)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 			task := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 
 			tc.mock(task)
@@ -3110,7 +3110,7 @@ func TestService_handleTaskFail(t *testing.T) {
 			res := resource.NewMockResource(ctl)
 			dynconfig := configmocks.NewMockDynconfigInterface(ctl)
 			storage := storagemocks.NewMockStorage(ctl)
-			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: &config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
+			svc := New(&config.Config{Scheduler: mockSchedulerConfig, Metrics: config.MetricsConfig{EnablePeerHost: true}}, res, scheduler, dynconfig, storage)
 			task := resource.NewTask(mockTaskID, mockTaskURL, commonv1.TaskType_Normal, mockTaskURLMeta, resource.WithBackToSourceLimit(mockTaskBackToSourceLimit))
 
 			tc.mock(task)