# HG changeset patch # User Sascha L. Teichmann # Date 1538477900 -7200 # Node ID 0a563fef64a9259f62a4bef10979f071eb2fbcdd # Parent afd83fb3399d9f2a2ba158a4d96150d654f628d9 Reconfiguring GeoServer is now queued async. We should not reconfigure the remote until the initial config is done. diff -r afd83fb3399d -r 0a563fef64a9 cmd/gemma/main.go --- a/cmd/gemma/main.go Tue Oct 02 11:45:16 2018 +0200 +++ b/cmd/gemma/main.go Tue Oct 02 12:58:20 2018 +0200 @@ -39,7 +39,7 @@ prepareSessionStore() // Do GeoServer setup in background. - go geoserver.ConfigureBoot() + geoserver.Reconfigure(geoserver.PrepareGeoServer) m := mux.NewRouter() controllers.BindRoutes(m) diff -r afd83fb3399d -r 0a563fef64a9 pkg/geoserver/boot.go --- a/pkg/geoserver/boot.go Tue Oct 02 11:45:16 2018 +0200 +++ b/pkg/geoserver/boot.go Tue Oct 02 12:58:20 2018 +0200 @@ -7,11 +7,9 @@ "fmt" "io" "log" - "net" "net/http" "net/url" "strings" - "time" "gemma.intevation.de/gemma/pkg/config" "gemma.intevation.de/gemma/pkg/models" @@ -491,7 +489,7 @@ } } -func prepareGeoServer() error { +func PrepareGeoServer() error { if config.DBUser() == "" { log.Println("info: Need metamorphic db user to configure GeoServer") @@ -517,28 +515,3 @@ return nil } - -func ConfigureBoot() { - log.Println("Configure GeoServer...") - const maxTries = 10 - const sleep = time.Second * 5 - - for try := 1; try <= maxTries; try++ { - err := prepareGeoServer() - if err == nil { - break - } - if try < maxTries { - if uerr, ok := err.(*url.Error); ok { - if oerr, ok := uerr.Err.(*net.OpError); ok && oerr.Op == "dial" { - log.Printf("Failed attempt %d of %d to configure GeoServer. "+ - "Will try again in %s...\n", try, maxTries, sleep) - time.Sleep(sleep) - continue - } - } - } - log.Printf("warn: configure GeoServer failed: %v\n", err) - break - } -} diff -r afd83fb3399d -r 0a563fef64a9 pkg/geoserver/reconf.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/geoserver/reconf.go Tue Oct 02 12:58:20 2018 +0200 @@ -0,0 +1,67 @@ +package geoserver + +import ( + "container/list" + "log" + "net" + "net/url" + "sync" + "time" +) + +var ( + confQueue = list.New() + confQueueCond = sync.NewCond(new(sync.Mutex)) +) + +func init() { + go asyncConfigure() +} + +func asyncConfigure() { + for { + var fn func() error + confQueueCond.L.Lock() + for confQueue.Len() == 0 { + confQueueCond.Wait() + } + fn = confQueue.Remove(confQueue.Front()).(func() error) + confQueueCond.L.Unlock() + if err := reconfigure(fn); err != nil { + log.Printf("warn: configure GeoServer failed: %v\n", err) + } + } +} + +func reconfigure(fn func() error) error { + log.Println("Configure GeoServer...") + const ( + maxTries = 10 + sleep = time.Second * 5 + ) + var err error + for try := 1; try <= maxTries; try++ { + if err = fn(); err == nil { + break + } + if try < maxTries { + if uerr, ok := err.(*url.Error); ok { + if oerr, ok := uerr.Err.(*net.OpError); ok && oerr.Op == "dial" { + log.Printf("Failed attempt %d of %d to configure GeoServer. "+ + "Will try again in %s...\n", try, maxTries, sleep) + time.Sleep(sleep) + continue + } + } + } + break + } + return err +} + +func Reconfigure(fn func() error) { + confQueueCond.L.Lock() + defer confQueueCond.L.Unlock() + confQueue.PushBack(fn) + confQueueCond.Signal() +}