go: run requests scheduler from main
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
* also, actually quit serving on shutdown timeout
This commit is contained in:
parent
f2025395b2
commit
ec7a8ca61a
1
error.go
1
error.go
@ -10,4 +10,5 @@ var (
|
|||||||
errUnsupportedDBType = errors.New("DBTYPE can only be one of postgres or sqlite3")
|
errUnsupportedDBType = errors.New("DBTYPE can only be one of postgres or sqlite3")
|
||||||
errDBConnFailed = errors.New("Failed to open a connection to the database")
|
errDBConnFailed = errors.New("Failed to open a connection to the database")
|
||||||
errImportFailed = errors.New("Import of local breach data failed")
|
errImportFailed = errors.New("Import of local breach data failed")
|
||||||
|
errHIBPSchedulerFailed = errors.New("HIBP requests scheduler failed")
|
||||||
)
|
)
|
||||||
|
58
run.go
58
run.go
@ -11,6 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
"git.dotya.ml/mirre-mt/pcmt/config"
|
"git.dotya.ml/mirre-mt/pcmt/config"
|
||||||
"git.dotya.ml/mirre-mt/pcmt/ent"
|
"git.dotya.ml/mirre-mt/pcmt/ent"
|
||||||
moddb "git.dotya.ml/mirre-mt/pcmt/modules/db"
|
moddb "git.dotya.ml/mirre-mt/pcmt/modules/db"
|
||||||
|
"git.dotya.ml/mirre-mt/pcmt/modules/hibp"
|
||||||
"git.dotya.ml/mirre-mt/pcmt/modules/localbreach"
|
"git.dotya.ml/mirre-mt/pcmt/modules/localbreach"
|
||||||
"git.dotya.ml/mirre-mt/pcmt/slogging"
|
"git.dotya.ml/mirre-mt/pcmt/slogging"
|
||||||
)
|
)
|
||||||
@ -248,9 +250,9 @@ func run() error { //nolint:gocognit
|
|||||||
// channel used to check whether the app had troubles starting up.
|
// channel used to check whether the app had troubles starting up.
|
||||||
started := make(chan error, 1)
|
started := make(chan error, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
defer close(started)
|
defer close(started)
|
||||||
|
|
||||||
go func(ok chan error) {
|
|
||||||
p := setting.Port()
|
p := setting.Port()
|
||||||
h := setting.Host()
|
h := setting.Host()
|
||||||
|
|
||||||
@ -259,38 +261,60 @@ func run() error { //nolint:gocognit
|
|||||||
if err := e.Start(address); err != nil && err != http.ErrServerClosed {
|
if err := e.Start(address); err != nil && err != http.ErrServerClosed {
|
||||||
log.Error("troubles running the server, bailing...", "error", err)
|
log.Error("troubles running the server, bailing...", "error", err)
|
||||||
|
|
||||||
ok <- err
|
started <- err
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ok <- nil
|
started <- nil
|
||||||
}(started)
|
}()
|
||||||
|
|
||||||
quit := make(chan os.Signal, 1)
|
quit := make(chan os.Signal, 1)
|
||||||
|
schedQuit := make(chan os.Signal, 1)
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
signal.Notify(quit, os.Interrupt)
|
handleSigs(schedQuit, quit)
|
||||||
signal.Notify(quit, syscall.SIGTERM)
|
|
||||||
signal.Notify(quit, syscall.SIGHUP)
|
go func() {
|
||||||
|
wg.Add(1) // nolint:staticcheck
|
||||||
|
go hibp.RunReqScheduler(schedQuit, errCh, wg) // nolint:wsl
|
||||||
|
}()
|
||||||
|
|
||||||
// non-blocking channel receive.
|
// non-blocking channel receive.
|
||||||
select {
|
select {
|
||||||
|
// monitor the server start-up chan.
|
||||||
case err := <-started:
|
case err := <-started:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case err := <-errCh:
|
||||||
|
defer func() {
|
||||||
|
signal.Stop(quit)
|
||||||
|
|
||||||
|
close(quit)
|
||||||
|
close(errCh)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return errHIBPSchedulerFailed
|
||||||
|
}
|
||||||
|
|
||||||
case <-quit:
|
case <-quit:
|
||||||
|
// after the timeout the server forcefully quits.
|
||||||
shutdownTimeout := 10 * time.Second
|
shutdownTimeout := 10 * time.Second
|
||||||
|
|
||||||
|
log.Infof("Interrupt received, gracefully shutting down the server (timeout %s)", shutdownTimeout)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||||
defer func() {
|
defer func() {
|
||||||
log.Infof("Interrupt received, gracefully shutting down the server (timeout %s)", shutdownTimeout)
|
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
signal.Stop(quit)
|
signal.Stop(quit)
|
||||||
|
|
||||||
close(quit)
|
close(quit)
|
||||||
|
close(errCh)
|
||||||
|
|
||||||
log.Info("Bye!")
|
log.Info("Bye!")
|
||||||
}()
|
}()
|
||||||
@ -299,11 +323,29 @@ func run() error { //nolint:gocognit
|
|||||||
log.Error("There was an error shutting the server down")
|
log.Error("There was an error shutting the server down")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
log.Error("Failed to stop the server in time, yolo")
|
||||||
|
return ctx.Err()
|
||||||
|
|
||||||
|
default:
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleSigs configures given chans to be notified on os signals.
|
||||||
|
func handleSigs(chans ...chan os.Signal) {
|
||||||
|
sigs := []os.Signal{os.Interrupt, syscall.SIGHUP, syscall.SIGTERM}
|
||||||
|
|
||||||
|
for _, ch := range chans {
|
||||||
|
signal.Notify(ch, sigs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func printHeader() {
|
func printHeader() {
|
||||||
slug := fmt.Sprintf(slug, version)
|
slug := fmt.Sprintf(slug, version)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user