summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod2
-rw-r--r--service/reload/service.go83
-rw-r--r--service/reload/watcher.go2
3 files changed, 56 insertions, 31 deletions
diff --git a/go.mod b/go.mod
index 8513085e..57ffd209 100644
--- a/go.mod
+++ b/go.mod
@@ -10,8 +10,6 @@ require (
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
- github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
- github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.4.1
diff --git a/service/reload/service.go b/service/reload/service.go
index 359b3331..832ac185 100644
--- a/service/reload/service.go
+++ b/service/reload/service.go
@@ -2,11 +2,11 @@ package reload
import (
"errors"
- "fmt"
"github.com/sirupsen/logrus"
"github.com/spiral/roadrunner"
"github.com/spiral/roadrunner/service"
"os"
+ "runtime"
"strings"
"time"
)
@@ -18,6 +18,7 @@ type Service struct {
cfg *Config
log *logrus.Logger
watcher *Watcher
+ stopc chan struct{}
}
// Init controller service
@@ -28,6 +29,7 @@ func (s *Service) Init(cfg *Config, log *logrus.Logger, c service.Container) (bo
s.cfg = cfg
s.log = log
+ s.stopc = make(chan struct{})
var configs []WatcherConfig
@@ -81,44 +83,67 @@ func (s *Service) Serve() error {
return errors.New("reload interval is too fast")
}
+ // make a map with unique services
+ // so, if we would have a 100 events from http service
+ // in map we would see only 1 key and it's config
+ treshholdc := make(chan struct {
+ serviceConfig ServiceConfig
+ service string
+ }, 100)
+
+ // drain channel in case of leaved messages
+ defer func() {
+ go func() {
+ for range treshholdc {
+
+ }
+ }()
+ }()
+
go func() {
for e := range s.watcher.Event {
+ s.log.Debugf("[UPDATE] Service: %s, path to file: %s, filename: %s", e.service, e.path, e.info.Name())
+
+ treshholdc <- struct {
+ serviceConfig ServiceConfig
+ service string
+ }{serviceConfig: s.cfg.Services[e.service], service: e.service}
- println(fmt.Sprintf("[UPDATE] Service: %s, path to file: %s, filename: %s", e.service, e.path, e.info.Name()))
+ }
+ }()
+
+ // use the same interval
+ ticker := time.NewTicker(s.cfg.Interval)
- srv := s.cfg.Services[e.service]
+ // map with configs by services
+ updated := make(map[string]ServiceConfig, 100)
- if srv.service != nil {
- sv := *srv.service
- err := sv.Server().Reset()
- if err != nil {
- s.log.Error(err)
+ go func() {
+ for {
+ select {
+ case config := <-treshholdc:
+ // replace previous value in map by more recent without adding new one
+ updated[config.service] = config.serviceConfig
+ case <-ticker.C:
+ if len(updated) > 0 {
+ for k, v := range updated {
+ sv := *v.service
+ err := sv.Server().Reset()
+ if err != nil {
+ s.log.Error(err)
+ }
+ s.log.Debugf("found file changes in %s service, reloading", k)
+ }
+ // zero map
+ updated = make(map[string]ServiceConfig, 100)
}
- } else {
- s.watcher.mu.Lock()
- delete(s.watcher.watcherConfigs, e.service)
- s.watcher.mu.Unlock()
+ case <-s.stopc:
+ ticker.Stop()
+ runtime.Goexit()
}
}
}()
- //go func() {
- // for {
- // select {
- // case <-update:
- // updated = append(updated, update)
- // case <-time.Ticker:
- // updated = updated[0:0]
- // err := sv.Server().Reset()
- // s.log.Debugf(
- // "reload %s, found file changes in %s",
- // strings.Join(updated, ","),
- // )
- // case <-exit:
- // }
- // }
- //}()
-
err := s.watcher.StartPolling(s.cfg.Interval)
if err != nil {
return err
diff --git a/service/reload/watcher.go b/service/reload/watcher.go
index 6c0ba86c..3596ae73 100644
--- a/service/reload/watcher.go
+++ b/service/reload/watcher.go
@@ -382,6 +382,7 @@ func (w *Watcher) pollEvents(serviceName string, files map[string]os.FileInfo) {
//Send all the remaining create and remove events.
for pth, info := range creates {
+ w.watcherConfigs[serviceName].files[pth] = info
w.Event <- Event{
path: pth,
info: info,
@@ -389,6 +390,7 @@ func (w *Watcher) pollEvents(serviceName string, files map[string]os.FileInfo) {
}
}
for pth, info := range removes {
+ delete(w.watcherConfigs[serviceName].files, pth)
w.Event <- Event{
path: pth,
info: info,