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

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

View File

@ -7,6 +7,7 @@ import (
"encoding/base64"
"fmt"
"net"
"net/http"
"net/url"
"os"
"strings"
@ -67,19 +68,32 @@ func (r *route) parseChain() (*gost.Chain, error) {
)
if cfg := nodes[0].Get("peer"); cfg != "" {
f, err := os.Open(cfg)
if err != nil {
return nil, err
}
peerCfg := newPeerConfig()
peerCfg.group = ngroup
peerCfg.baseNodes = nodes
peerCfg.Reload(f)
f.Close()
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)
}

View File

@ -1,7 +1,9 @@
package gost
import (
"fmt"
"io"
"net/http"
"os"
"time"
@ -63,3 +65,39 @@ func PeriodReload(r Reloader, configFile string) error {
<-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)
}
}