add support for loading peerConfig from a url

This commit is contained in:
harmy 2020-11-23 12:24:51 +08:00
parent 3ea5708819
commit 6eb7590bc3
3 changed files with 70 additions and 18 deletions

View File

@ -14,14 +14,14 @@ import (
) )
type peerConfig struct { type peerConfig struct {
Strategy string `json:"strategy"` Strategy string `json:"strategy"`
MaxFails int `json:"max_fails"` MaxFails int `json:"max_fails"`
FailTimeout time.Duration FailTimeout time.Duration `json:"fail_timeout"`
period time.Duration // the period for live reloading ReloadPeriod time.Duration `json:"reload"`
Nodes []string `json:"nodes"` Nodes []string `json:"nodes"`
group *gost.NodeGroup group *gost.NodeGroup
baseNodes []gost.Node baseNodes []gost.Node
stopped chan struct{} stopped chan struct{}
} }
func newPeerConfig() *peerConfig { func newPeerConfig() *peerConfig {
@ -129,7 +129,7 @@ func (cfg *peerConfig) parse(r io.Reader) error {
case "fail_timeout": case "fail_timeout":
cfg.FailTimeout, _ = time.ParseDuration(ss[1]) cfg.FailTimeout, _ = time.ParseDuration(ss[1])
case "reload": case "reload":
cfg.period, _ = time.ParseDuration(ss[1]) cfg.ReloadPeriod, _ = time.ParseDuration(ss[1])
case "peer": case "peer":
cfg.Nodes = append(cfg.Nodes, ss[1]) cfg.Nodes = append(cfg.Nodes, ss[1])
} }
@ -142,7 +142,7 @@ func (cfg *peerConfig) Period() time.Duration {
if cfg.Stopped() { if cfg.Stopped() {
return -1 return -1
} }
return cfg.period return cfg.ReloadPeriod
} }
// Stop stops reloading. // Stop stops reloading.

View File

@ -7,6 +7,7 @@ import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"net" "net"
"net/http"
"net/url" "net/url"
"os" "os"
"strings" "strings"
@ -67,18 +68,31 @@ func (r *route) parseChain() (*gost.Chain, error) {
) )
if cfg := nodes[0].Get("peer"); cfg != "" { if cfg := nodes[0].Get("peer"); cfg != "" {
f, err := os.Open(cfg)
if err != nil {
return nil, err
}
peerCfg := newPeerConfig() peerCfg := newPeerConfig()
peerCfg.group = ngroup peerCfg.group = ngroup
peerCfg.baseNodes = nodes peerCfg.baseNodes = nodes
peerCfg.Reload(f)
f.Close()
go gost.PeriodReload(peerCfg, cfg) if strings.HasPrefix(cfg, "http") {
client := http.Client{}
resp, err := client.Get(cfg)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("fetch remote resource error, reply status code is not equals to 200")
}
peerCfg.Reload(resp.Body)
go gost.PeriodReloadRemote(peerCfg, cfg)
} else {
f, err := os.Open(cfg)
defer f.Close()
if err != nil {
return nil, err
}
peerCfg.Reload(f)
go gost.PeriodReload(peerCfg, cfg)
}
} }
chain.AddNodeGroup(ngroup) chain.AddNodeGroup(ngroup)

View File

@ -1,7 +1,9 @@
package gost package gost
import ( import (
"fmt"
"io" "io"
"net/http"
"os" "os"
"time" "time"
@ -63,3 +65,39 @@ func PeriodReload(r Reloader, configFile string) error {
<-time.After(period) <-time.After(period)
} }
} }
// PeriodReloadRemote reloads the remote configFile periodically according to the period of the Reloader r.
func PeriodReloadRemote(r Reloader, cfg string) error {
if r == nil || cfg == "" {
return nil
}
client := http.Client{}
for {
if r.Period() < 0 {
log.Log("[reload] stopped:", cfg)
return nil
}
resp, err := client.Get(cfg)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("fetch remote resource error, reply status code is not equals to 200")
}
if err := r.Reload(resp.Body); err != nil {
log.Logf("[reload] %s: %s", cfg, err)
}
period := r.Period()
if period == 0 {
log.Log("[reload] disabled:", cfg)
return nil
}
if period < time.Second {
period = time.Second
}
<-time.After(period)
}
}