1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-02 15:36:41 -05:00

parse duration conf with time.Parse()

This commit is contained in:
jebbs 2021-06-05 13:00:14 +01:00 committed by Shelikhoo
parent 718d6f32bf
commit a8dd708028
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316
4 changed files with 91 additions and 20 deletions

33
infra/conf/duration.go Normal file
View File

@ -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)
}
}

View File

@ -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))
}
}

View File

@ -1,8 +1,6 @@
package conf
import (
"time"
"github.com/golang/protobuf/proto"
"github.com/v2fly/v2ray-core/v4/app/router"
@ -29,22 +27,29 @@ func (v *strategyEmptyConfig) Build() (proto.Message, error) {
}
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
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 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
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.
func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
config := &router.StrategyLeastLoadConfig{
@ -54,8 +59,8 @@ func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
config.HealthCheck = &router.HealthPingConfig{
Destination: v.HealthCheck.Destination,
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),
}
}
@ -71,7 +76,7 @@ func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
if config.Expected < 0 {
config.Expected = 0
}
config.MaxRTT = int64(time.Duration(v.MaxRTT) * time.Millisecond)
config.MaxRTT = int64(v.MaxRTT)
if config.MaxRTT < 0 {
config.MaxRTT = 0
}
@ -80,7 +85,7 @@ func (v *strategyLeastLoadConfig) Build() (proto.Message, error) {
if b <= 0 {
continue
}
config.Baselines = append(config.Baselines, int64(time.Duration(b)*time.Millisecond))
config.Baselines = append(config.Baselines, int64(b))
}
return config, nil
}

View File

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