author | Alberto Bertogli
<albertito@blitiri.com.ar> 2022-10-14 10:10:15 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2022-10-14 10:10:15 UTC |
parent | 759773f36c718248812b59dd0bacbf361d780743 |
debug/debug.go | +2 | -2 |
gofer.go | +51 | -9 |
reqlog/reqlog.go | +1 | -2 |
server/http.go | +19 | -14 |
server/raw.go | +4 | -4 |
diff --git a/debug/debug.go b/debug/debug.go index fb69d16..26cddab 100644 --- a/debug/debug.go +++ b/debug/debug.go @@ -37,7 +37,7 @@ func init() { SourceDateStr = SourceDate.Format("2006-01-02 15:04:05 -0700") } -func ServeDebugging(addr string, conf *config.Config) { +func ServeDebugging(addr string, conf *config.Config) error { hostname, _ := os.Hostname() indexData := struct { @@ -70,7 +70,7 @@ func ServeDebugging(addr string, conf *config.Config) { log.Infof("debugging HTTP server listening on %q", addr) err := http.ListenAndServe(addr, nil) - log.Errorf("debugging HTTP server died: %v", err) + return log.Errorf("debugging HTTP server died: %v", err) } func DumpConfigFunc(conf *config.Config) http.HandlerFunc { diff --git a/gofer.go b/gofer.go index 68ff250..e065ad6 100644 --- a/gofer.go +++ b/gofer.go @@ -5,8 +5,8 @@ import ( "fmt" "os" "os/signal" + "sync" "syscall" - "time" "blitiri.com.ar/go/gofer/config" "blitiri.com.ar/go/gofer/debug" @@ -56,28 +56,46 @@ func main() { go signalHandler() for name, rlog := range conf.ReqLog { - reqlog.FromConfig(name, rlog) + err := reqlog.FromConfig(name, rlog) + if err != nil { + log.Fatalf(err.Error()) + } } + servers := []runnerFunc{} + for addr, https := range conf.HTTPS { - go server.HTTPS(addr, https) + addr := addr + https := https + servers = append(servers, func() error { + return server.HTTPS(addr, https) + }) } for addr, http := range conf.HTTP { - go server.HTTP(addr, http) + addr := addr + http := http + servers = append(servers, func() error { + return server.HTTP(addr, http) + }) } for addr, raw := range conf.Raw { - go server.Raw(addr, raw) + addr := addr + raw := raw + servers = append(servers, func() error { + return server.Raw(addr, raw) + }) } if conf.ControlAddr != "" { - go debug.ServeDebugging(conf.ControlAddr, conf) + servers = append(servers, func() error { + return debug.ServeDebugging(conf.ControlAddr, conf) + }) } - for { - time.Sleep(1 * time.Hour) - } + err = runMany(servers...) + log.Fatalf(err.Error()) } func signalHandler() { @@ -102,3 +120,27 @@ func signalHandler() { } } } + +type runnerFunc func() error + +func runMany(fs ...runnerFunc) error { + var err error + mu := &sync.Mutex{} + cond := sync.NewCond(mu) + + mu.Lock() + + for _, f := range fs { + go func(f runnerFunc) { + e := f() + mu.Lock() + err = e + cond.Broadcast() + mu.Unlock() + }(f) + } + + cond.Wait() + + return err +} diff --git a/reqlog/reqlog.go b/reqlog/reqlog.go index 942e84e..8e41ce6 100644 --- a/reqlog/reqlog.go +++ b/reqlog/reqlog.go @@ -150,8 +150,7 @@ var registry = map[string]*Log{} func FromConfig(name string, conf config.ReqLog) error { h, err := New(conf.File, conf.BufSize, conf.Format) if err != nil { - log.Fatalf("reqlog %q failed to initialize: %v", name, err) - return err + return fmt.Errorf("reqlog %q failed to initialize: %v", name, err) } registry[name] = h log.Infof("reqlog %q writing to %q", name, conf.File) diff --git a/server/http.go b/server/http.go index 87aaf1b..384e9fd 100644 --- a/server/http.go +++ b/server/http.go @@ -22,7 +22,7 @@ import ( "blitiri.com.ar/go/systemd" ) -func httpServer(addr string, conf config.HTTP) *http.Server { +func httpServer(addr string, conf config.HTTP) (*http.Server, error) { tr := trace.New("httpserver", addr) tr.SetMaxEvents(1000) @@ -67,7 +67,7 @@ func httpServer(addr string, conf config.HTTP) *http.Server { for path, dbPath := range conf.Auth { users, err := LoadAuthFile(dbPath) if err != nil { - log.Fatalf( + return nil, log.Errorf( "failed to load auth file %q: %v", dbPath, err) } authMux.Handle(path, @@ -109,7 +109,7 @@ func httpServer(addr string, conf config.HTTP) *http.Server { for path, logName := range conf.ReqLog { l := reqlog.FromName(logName) if l == nil { - log.Fatalf("unknown reqlog name %q", logName) + return nil, log.Errorf("unknown reqlog name %q", logName) } logMux.Handle(path, WithReqLog(srv.Handler, l)) log.Infof("%s reqlog %q to %q", srv.Addr, path, logName) @@ -124,39 +124,44 @@ func httpServer(addr string, conf config.HTTP) *http.Server { // Tracing for all entries. srv.Handler = WithTrace("http@"+srv.Addr, srv.Handler) - return srv + return srv, nil } -func HTTP(addr string, conf config.HTTP) { - srv := httpServer(addr, conf) +func HTTP(addr string, conf config.HTTP) error { + srv, err := httpServer(addr, conf) + if err != nil { + return err + } lis, err := systemd.Listen("tcp", addr) if err != nil { - log.Fatalf("%s error listening: %v", addr, err) + return log.Errorf("%s error listening: %v", addr, err) } log.Infof("%s http starting on %q", addr, lis.Addr()) err = srv.Serve(lis) - log.Fatalf("%s http exited: %v", addr, err) + return log.Errorf("%s http exited: %v", addr, err) } -func HTTPS(addr string, conf config.HTTPS) { - var err error - srv := httpServer(addr, conf.HTTP) +func HTTPS(addr string, conf config.HTTPS) error { + srv, err := httpServer(addr, conf.HTTP) + if err != nil { + return err + } srv.TLSConfig, err = util.LoadCertsForHTTPS(conf) if err != nil { - log.Fatalf("%s error loading certs: %v", addr, err) + return log.Errorf("%s error loading certs: %v", addr, err) } rawLis, err := systemd.Listen("tcp", addr) if err != nil { - log.Fatalf("%s error listening: %v", addr, err) + return log.Errorf("%s error listening: %v", addr, err) } lis := tls.NewListener(rawLis, srv.TLSConfig) log.Infof("%s https starting on %q", addr, lis.Addr()) err = srv.Serve(lis) - log.Fatalf("%s https exited: %v", addr, err) + return log.Errorf("%s https exited: %v", addr, err) } // joinPath joins to HTTP paths. We can't use path.Join because it strips the diff --git a/server/raw.go b/server/raw.go index 37196ba..b5bcd15 100644 --- a/server/raw.go +++ b/server/raw.go @@ -14,14 +14,14 @@ import ( "blitiri.com.ar/go/systemd" ) -func Raw(addr string, conf config.Raw) { +func Raw(addr string, conf config.Raw) error { var err error var tlsConfig *tls.Config if conf.Certs != "" { tlsConfig, err = util.LoadCertsFromDir(conf.Certs) if err != nil { - log.Fatalf("error loading certs: %v", err) + return log.Errorf("error loading certs: %v", err) } } @@ -33,7 +33,7 @@ func Raw(addr string, conf config.Raw) { lis, err = systemd.Listen("tcp", addr) } if err != nil { - log.Fatalf("Raw proxy error listening on %q: %v", addr, err) + return log.Errorf("Raw proxy error listening on %q: %v", addr, err) } rlog := reqlog.FromName(conf.ReqLog) @@ -42,7 +42,7 @@ func Raw(addr string, conf config.Raw) { for { conn, err := lis.Accept() if err != nil { - log.Fatalf("%s error accepting: %v", addr, err) + return log.Errorf("%s error accepting: %v", addr, err) } go forward(conn, conf.To, conf.ToTLS, rlog)