Browse Source

parse duration conf with time.Parse()

jebbs 4 years ago
parent
commit
a8dd708028
4 changed files with 91 additions and 20 deletions
  1. 33 0
      infra/conf/duration.go
  2. 33 0
      infra/conf/duration_test.go
  3. 19 14
      infra/conf/router_strategy.go
  4. 6 6
      infra/conf/router_test.go

+ 33 - 0
infra/conf/duration.go

@@ -0,0 +1,33 @@
+package conf
+
+import (
+	"encoding/json"
+	"fmt"
+	"time"
+)
+
+type Duration int64
+
+func (d *Duration) MarshalJSON() ([]byte, error) {
+	dr := time.Duration(*d)
+	return json.Marshal(dr.String())
+}
+
+func (d *Duration) UnmarshalJSON(b []byte) error {
+	var v interface{}
+	if err := json.Unmarshal(b, &v); err != nil {
+		return err
+	}
+	switch value := v.(type) {
+	case string:
+		var err error
+		dr, err := time.ParseDuration(value)
+		if err != nil {
+			return err
+		}
+		*d = Duration(dr)
+		return nil
+	default:
+		return fmt.Errorf("invalid duration: %v", v)
+	}
+}

+ 33 - 0
infra/conf/duration_test.go

@@ -0,0 +1,33 @@
+package conf_test
+
+import (
+	"encoding/json"
+	"testing"
+	"time"
+
+	"github.com/v2fly/v2ray-core/v4/infra/conf"
+)
+
+type testWithDuration struct {
+	Duration conf.Duration
+}
+
+func TestDurationJSON(t *testing.T) {
+	expected := &testWithDuration{
+		Duration: conf.Duration(time.Hour),
+	}
+	data, err := json.Marshal(expected)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	actual := &testWithDuration{}
+	err = json.Unmarshal(data, &actual)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if actual.Duration != expected.Duration {
+		t.Errorf("expected: %s, actual: %s", time.Duration(expected.Duration), time.Duration(actual.Duration))
+	}
+}

+ 19 - 14
infra/conf/router_strategy.go

@@ -1,8 +1,6 @@
 package conf
 package conf
 
 
 import (
 import (
-	"time"
-
 	"github.com/golang/protobuf/proto"
 	"github.com/golang/protobuf/proto"
 
 
 	"github.com/v2fly/v2ray-core/v4/app/router"
 	"github.com/v2fly/v2ray-core/v4/app/router"
@@ -29,22 +27,29 @@ func (v *strategyEmptyConfig) Build() (proto.Message, error) {
 }
 }
 
 
 type strategyLeastLoadConfig struct {
 type strategyLeastLoadConfig struct {
-	// note the time values of the HealthCheck holds is not
-	// 'time.Duration' but plain number, sice they were parsed
-	// directly from json
-	HealthCheck *router.HealthPingSettings `json:"healthCheck,omitempty"`
+	// health check settings
+	HealthCheck *healthCheckSettings `json:"healthCheck,omitempty"`
 	// weight settings
 	// weight settings
 	Costs []*router.StrategyWeight `json:"costs,omitempty"`
 	Costs []*router.StrategyWeight `json:"costs,omitempty"`
-	// ping rtt baselines (ms)
-	Baselines []int `json:"baselines,omitempty"`
+	// ping rtt baselines
+	Baselines []Duration `json:"baselines,omitempty"`
 	// expected nodes count to select
 	// expected nodes count to select
 	Expected int32 `json:"expected,omitempty"`
 	Expected int32 `json:"expected,omitempty"`
-	// max acceptable rtt (ms), filter away high delay nodes. defalut 0
-	MaxRTT int `json:"maxRTT,omitempty"`
+	// max acceptable rtt, filter away high delay nodes. defalut 0
+	MaxRTT Duration `json:"maxRTT,omitempty"`
 	// acceptable failure rate
 	// acceptable failure rate
 	Tolerance float64 `json:"tolerance,omitempty"`
 	Tolerance float64 `json:"tolerance,omitempty"`
 }
 }
 
 
+// healthCheckSettings holds settings for health Checker
+type healthCheckSettings struct {
+	Destination   string   `json:"destination"`
+	Connectivity  string   `json:"connectivity"`
+	Interval      Duration `json:"interval"`
+	SamplingCount int      `json:"sampling"`
+	Timeout       Duration `json:"timeout"`
+}
+
 // Build implements Buildable.
 // Build implements Buildable.
 func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
 func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
 	config := &router.StrategyLeastLoadConfig{
 	config := &router.StrategyLeastLoadConfig{
@@ -54,8 +59,8 @@ func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
 		config.HealthCheck = &router.HealthPingConfig{
 		config.HealthCheck = &router.HealthPingConfig{
 			Destination:   v.HealthCheck.Destination,
 			Destination:   v.HealthCheck.Destination,
 			Connectivity:  v.HealthCheck.Connectivity,
 			Connectivity:  v.HealthCheck.Connectivity,
-			Interval:      int64(v.HealthCheck.Interval * time.Second),
-			Timeout:       int64(v.HealthCheck.Timeout * time.Second),
+			Interval:      int64(v.HealthCheck.Interval),
+			Timeout:       int64(v.HealthCheck.Timeout),
 			SamplingCount: int32(v.HealthCheck.SamplingCount),
 			SamplingCount: int32(v.HealthCheck.SamplingCount),
 		}
 		}
 	}
 	}
@@ -71,7 +76,7 @@ func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
 	if config.Expected < 0 {
 	if config.Expected < 0 {
 		config.Expected = 0
 		config.Expected = 0
 	}
 	}
-	config.MaxRTT = int64(time.Duration(v.MaxRTT) * time.Millisecond)
+	config.MaxRTT = int64(v.MaxRTT)
 	if config.MaxRTT < 0 {
 	if config.MaxRTT < 0 {
 		config.MaxRTT = 0
 		config.MaxRTT = 0
 	}
 	}
@@ -80,7 +85,7 @@ func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
 		if b <= 0 {
 		if b <= 0 {
 			continue
 			continue
 		}
 		}
-		config.Baselines = append(config.Baselines, int64(time.Duration(b)*time.Millisecond))
+		config.Baselines = append(config.Baselines, int64(b))
 	}
 	}
 	return config, nil
 	return config, nil
 }
 }

+ 6 - 6
infra/conf/router_test.go

@@ -78,9 +78,9 @@ func TestRouterConfig(t *testing.T) {
 							"type": "leastload",
 							"type": "leastload",
 							"settings": {
 							"settings": {
 								"healthCheck": {
 								"healthCheck": {
-									"interval": 300,
+									"interval": "5m0s",
 									"sampling": 2,
 									"sampling": 2,
-									"timeout": 3,
+									"timeout": "5s",
 									"destination": "dest",
 									"destination": "dest",
 									"connectivity": "conn"
 									"connectivity": "conn"
 								},
 								},
@@ -91,9 +91,9 @@ func TestRouterConfig(t *testing.T) {
 										"value": 5
 										"value": 5
 									}
 									}
 								],
 								],
-								"baselines": [400, 600],
+								"baselines": ["400ms", "600ms"],
 								"expected": 6,
 								"expected": 6,
-								"maxRTT": 1000,
+								"maxRTT": "1000ms",
 								"tolerance": 0.5
 								"tolerance": 0.5
 							}
 							}
 						},
 						},
@@ -116,9 +116,9 @@ func TestRouterConfig(t *testing.T) {
 						Strategy:         "leastload",
 						Strategy:         "leastload",
 						StrategySettings: serial.ToTypedMessage(&router.StrategyLeastLoadConfig{
 						StrategySettings: serial.ToTypedMessage(&router.StrategyLeastLoadConfig{
 							HealthCheck: &router.HealthPingConfig{
 							HealthCheck: &router.HealthPingConfig{
-								Interval:      int64(time.Duration(300) * time.Second),
+								Interval:      int64(time.Duration(5) * time.Minute),
 								SamplingCount: 2,
 								SamplingCount: 2,
-								Timeout:       int64(time.Duration(3) * time.Second),
+								Timeout:       int64(time.Duration(5) * time.Second),
 								Destination:   "dest",
 								Destination:   "dest",
 								Connectivity:  "conn",
 								Connectivity:  "conn",
 							},
 							},