go: run requests scheduler from main
All checks were successful
continuous-integration/drone/push Build is passing

* also, actually quit serving on shutdown timeout
This commit is contained in:
surtur 2023-08-22 20:56:32 +02:00
parent f2025395b2
commit ec7a8ca61a
Signed by: wanderer
SSH Key Fingerprint: SHA256:MdCZyJ2sHLltrLBp0xQO0O1qTW9BT/xl5nXkDvhlMCI
2 changed files with 56 additions and 13 deletions

@ -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

@ -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)