From 65b31ca55191ba212cb4b5f4d8308789a287ba92 Mon Sep 17 00:00:00 2001 From: Michael Murphy <36900417+murphymj25@users.noreply.github.com> Date: Wed, 17 Apr 2019 10:48:03 -0500 Subject: [PATCH] Fix Memory Leak in WatchBackend - fixes #595 --- main.go | 20 ++++++++++---------- route/parse_new.go | 25 ++++++++++++++----------- route/table.go | 3 +-- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/main.go b/main.go index d2481c982..a751626a7 100644 --- a/main.go +++ b/main.go @@ -432,6 +432,7 @@ func watchBackend(cfg *config.Config, first chan bool) { svccfg string mancfg string customBE string + next bytes.Buffer once sync.Once ) @@ -454,19 +455,21 @@ func watchBackend(cfg *config.Config, first chan bool) { man := registry.Default.WatchManual() for { + select { case svccfg = <-svc: case mancfg = <-man: } - // manual config overrides service config // order matters - next := svccfg + "\n" + mancfg - if next == last { + next.Reset() + next.WriteString(svccfg) + next.WriteString("\n") + next.WriteString(mancfg) + if next.String() == last { continue } - - aliases, err := route.ParseAliases(next) + aliases, err := route.ParseAliases(next.String()) if err != nil { log.Printf("[WARN]: %s", err) } @@ -478,14 +481,11 @@ func watchBackend(cfg *config.Config, first chan bool) { continue } route.SetTable(t) - logRoutes(t, last, next, cfg.Log.RoutesFormat) - last = next - + logRoutes(t, last, next.String(), cfg.Log.RoutesFormat) + last = next.String() once.Do(func() { close(first) }) } - } - } func watchNoRouteHTML(cfg *config.Config) { diff --git a/route/parse_new.go b/route/parse_new.go index 1ea9d5486..095343968 100644 --- a/route/parse_new.go +++ b/route/parse_new.go @@ -1,6 +1,8 @@ package route import ( + "bufio" + "bytes" "errors" "fmt" "regexp" @@ -65,25 +67,26 @@ route weight service host/path weight w tags "tag1,tag2" // The commands are parsed in order and order matters. // Deleting a route that has not been created yet yields // a different result than the other way around. -func Parse(in string) (defs []*RouteDef, err error) { +func Parse(in bytes.Buffer) (defs []*RouteDef, err error) { var def *RouteDef - for i, s := range strings.Split(in, "\n") { + scanner := bufio.NewScanner(&in) + for scanner.Scan() { def, err = nil, nil - s = strings.TrimSpace(s) + result := strings.TrimSpace(scanner.Text()) switch { - case reComment.MatchString(s) || reBlankLine.MatchString(s): + case reComment.MatchString(result) || reBlankLine.MatchString(result): continue - case reRouteAdd.MatchString(s): - def, err = parseRouteAdd(s) - case reRouteDel.MatchString(s): - def, err = parseRouteDel(s) - case reRouteWeight.MatchString(s): - def, err = parseRouteWeight(s) + case reRouteAdd.MatchString(result): + def, err = parseRouteAdd(result) + case reRouteDel.MatchString(result): + def, err = parseRouteDel(result) + case reRouteWeight.MatchString(result): + def, err = parseRouteWeight(result) default: err = errors.New("syntax error: 'route' expected") } if err != nil { - return nil, fmt.Errorf("line %d: %s", i+1, err) + return nil, fmt.Errorf("line %d: %s", err) } defs = append(defs, def) } diff --git a/route/table.go b/route/table.go index 13c874289..ee0ce9d9c 100644 --- a/route/table.go +++ b/route/table.go @@ -108,8 +108,7 @@ func hostpath(prefix string) (host string, path string) { return p[0], "/" + p[1] } -func NewTable(s string) (t Table, err error) { - +func NewTable(s bytes.Buffer) (t Table, err error) { defs, err := Parse(s) if err != nil { return nil, err