mirror of
https://github.com/photoprism/photoprism.git
synced 2025-09-26 21:01:58 +08:00
Server: Add standard liveness/readiness check endpoints
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -33,6 +33,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
@@ -78,6 +79,7 @@ type Config struct {
|
||||
serial string
|
||||
env string
|
||||
start bool
|
||||
ready atomic.Bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -266,10 +268,16 @@ func (c *Config) Init() error {
|
||||
|
||||
// Show log message.
|
||||
log.Debugf("config: successfully initialized [%s]", time.Since(start))
|
||||
c.ready.Store(true)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsReady checks if the application has been successfully initialized.
|
||||
func (c *Config) IsReady() bool {
|
||||
return c.ready.Load()
|
||||
}
|
||||
|
||||
// Propagate updates config options in other packages as needed.
|
||||
func (c *Config) Propagate() {
|
||||
FlushCache()
|
||||
@@ -599,6 +607,9 @@ func (c *Config) SetLogLevel(level logrus.Level) {
|
||||
|
||||
// Shutdown shuts down the active processes and closes the database connection.
|
||||
func (c *Config) Shutdown() {
|
||||
// App is no longer accepting requests.
|
||||
c.ready.Store(false)
|
||||
|
||||
// Send cancel signal to all workers.
|
||||
mutex.CancelAll()
|
||||
|
||||
|
@@ -111,12 +111,27 @@ func Start(ctx context.Context, conf *config.Config) {
|
||||
// Register application routes.
|
||||
registerRoutes(router, conf)
|
||||
|
||||
// Register "GET /health" route so clients can perform health checks.
|
||||
router.GET(conf.BaseUri("/health"), func(c *gin.Context) {
|
||||
// Register standard health check endpoints to determine whether the server is running.
|
||||
isLive := func(c *gin.Context) {
|
||||
c.Header(header.CacheControl, header.CacheControlNoStore)
|
||||
c.Header(header.AccessControlAllowOrigin, header.Any)
|
||||
c.String(http.StatusOK, "OK")
|
||||
})
|
||||
}
|
||||
router.Any(conf.BaseUri("/livez"), isLive)
|
||||
router.Any(conf.BaseUri("/health"), isLive)
|
||||
router.Any(conf.BaseUri("/healthz"), isLive)
|
||||
|
||||
// Register "/readyz" endpoint to check if the server has been successfully initialized.
|
||||
isReady := func(c *gin.Context) {
|
||||
c.Header(header.CacheControl, header.CacheControlNoStore)
|
||||
c.Header(header.AccessControlAllowOrigin, header.Any)
|
||||
if conf.IsReady() {
|
||||
c.String(http.StatusOK, "OK")
|
||||
} else {
|
||||
c.String(http.StatusServiceUnavailable, "Service Unavailable")
|
||||
}
|
||||
}
|
||||
router.Any(conf.BaseUri("/readyz"), isReady)
|
||||
|
||||
// Create a new HTTP server instance with no read or write timeout, except for reading the headers:
|
||||
// https://pkg.go.dev/net/http#Server
|
||||
|
Reference in New Issue
Block a user