mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-21 13:35:49 +02:00
fixed graceful shutdown handling
This commit is contained in:
parent
d86e20b7f2
commit
506b759560
@ -78,6 +78,8 @@
|
|||||||
- Trigger the `app.OnTerminate()` hook on `app.Restart()` call.
|
- Trigger the `app.OnTerminate()` hook on `app.Restart()` call.
|
||||||
_A new bool `IsRestart` field was also added to the `core.TerminateEvent` event._
|
_A new bool `IsRestart` field was also added to the `core.TerminateEvent` event._
|
||||||
|
|
||||||
|
- Fixed the graceful shutdown handling.
|
||||||
|
|
||||||
|
|
||||||
## v0.20.0-rc3
|
## v0.20.0-rc3
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
@ -189,14 +190,37 @@ func Serve(app core.App, config ServeConfig) (*http.Server, error) {
|
|||||||
regular.Printf("└─ Admin UI: %s\n", color.CyanString("%s://%s/_/", schema, addr))
|
regular.Printf("└─ Admin UI: %s\n", color.CyanString("%s://%s/_/", schema, addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WaitGroup to block until server.ShutDown() returns because Serve and similar methods exit immediately.
|
||||||
|
// Note that the WaitGroup would not do anything if the app.OnTerminate() hook isn't triggered.
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
// try to gracefully shutdown the server on app termination
|
// try to gracefully shutdown the server on app termination
|
||||||
app.OnTerminate().Add(func(e *core.TerminateEvent) error {
|
app.OnTerminate().Add(func(e *core.TerminateEvent) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
server.Shutdown(ctx)
|
server.Shutdown(ctx)
|
||||||
|
if e.IsRestart {
|
||||||
|
// wait for execve up to 3 seconds before exit
|
||||||
|
time.AfterFunc(3*time.Second, func() {
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
wg.Done()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// wait for the graceful shutdown to complete before exit
|
||||||
|
defer wg.Wait()
|
||||||
|
|
||||||
|
// ---
|
||||||
|
// @todo consider removing the server return value because it is
|
||||||
|
// not really useful when combined with the blocking serve calls
|
||||||
|
// ---
|
||||||
|
|
||||||
// start HTTPS server
|
// start HTTPS server
|
||||||
if config.HttpsAddr != "" {
|
if config.HttpsAddr != "" {
|
||||||
// if httpAddr is set, start an HTTP server to redirect the traffic to the HTTPS version
|
// if httpAddr is set, start an HTTP server to redirect the traffic to the HTTPS version
|
||||||
|
17
core/base.go
17
core/base.go
@ -553,20 +553,15 @@ func (app *BaseApp) Restart() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// restart the app bootstrap as a fallback in case the
|
return app.OnTerminate().Trigger(&TerminateEvent{
|
||||||
// terminate event or execve fails for some reason
|
|
||||||
defer app.Bootstrap()
|
|
||||||
|
|
||||||
// optimistically trigger the terminate event
|
|
||||||
terminateErr := app.OnTerminate().Trigger(&TerminateEvent{
|
|
||||||
App: app,
|
App: app,
|
||||||
IsRestart: true,
|
IsRestart: true,
|
||||||
})
|
}, func(e *TerminateEvent) error {
|
||||||
if terminateErr != nil {
|
// attempt to restart the bootstrap process in case execve returns an error for some reason
|
||||||
return terminateErr
|
defer app.Bootstrap()
|
||||||
}
|
|
||||||
|
|
||||||
return syscall.Exec(execPath, os.Args, os.Environ())
|
return syscall.Exec(execPath, os.Args, os.Environ())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshSettings reinitializes and reloads the stored application settings.
|
// RefreshSettings reinitializes and reloads the stored application settings.
|
||||||
|
@ -110,7 +110,7 @@ func main() {
|
|||||||
// GitHub selfupdate
|
// GitHub selfupdate
|
||||||
ghupdate.MustRegister(app, app.RootCmd, ghupdate.Config{})
|
ghupdate.MustRegister(app, app.RootCmd, ghupdate.Config{})
|
||||||
|
|
||||||
app.OnAfterBootstrap().Add(func(e *core.BootstrapEvent) error {
|
app.OnAfterBootstrap().PreAdd(func(e *core.BootstrapEvent) error {
|
||||||
app.Dao().ModelQueryTimeout = time.Duration(queryTimeout) * time.Second
|
app.Dao().ModelQueryTimeout = time.Duration(queryTimeout) * time.Second
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -152,12 +152,13 @@ func (pb *PocketBase) Execute() error {
|
|||||||
sigch := make(chan os.Signal, 1)
|
sigch := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
|
||||||
<-sigch
|
<-sigch
|
||||||
|
|
||||||
done <- true
|
done <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// execute the root command
|
// execute the root command
|
||||||
go func() {
|
go func() {
|
||||||
// leave to the commands to decide whether to print their error or not
|
// note: leave to the commands to decide whether to print their error
|
||||||
pb.RootCmd.Execute()
|
pb.RootCmd.Execute()
|
||||||
|
|
||||||
done <- true
|
done <- true
|
||||||
|
Loading…
Reference in New Issue
Block a user