[feature] Use maintenance router to serve 503 while server is starting/migrating (#3705)

* [feature] Use maintenance router to serve 503 while server is starting/migrating

* love you linter, kissies
This commit is contained in:
tobi 2025-01-29 16:57:04 +01:00 committed by GitHub
commit d16e4fa34d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 271 additions and 26 deletions

View file

@ -69,6 +69,36 @@ import (
"go.uber.org/automaxprocs/maxprocs"
)
// Maintenance starts and creates a GoToSocial server
// in maintenance mode (returns 503 for most requests).
var Maintenance action.GTSAction = func(ctx context.Context) error {
route, err := router.New(ctx)
if err != nil {
return fmt.Errorf("error creating maintenance router: %w", err)
}
// Route maintenance handlers.
maintenance := web.NewMaintenance()
maintenance.Route(route)
// Start the maintenance router.
if err := route.Start(); err != nil {
return fmt.Errorf("error starting maintenance router: %w", err)
}
// Catch shutdown signals from the OS.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigs // block until signal received
log.Infof(ctx, "received signal %s, shutting down", sig)
if err := route.Stop(); err != nil {
log.Errorf(ctx, "error stopping router: %v", err)
}
return nil
}
// Start creates and starts a gotosocial server
var Start action.GTSAction = func(ctx context.Context) error {
// Set GOMAXPROCS / GOMEMLIMIT
@ -148,6 +178,23 @@ var Start action.GTSAction = func(ctx context.Context) error {
log.Info(ctx, "done! exiting...")
}()
// Create maintenance router.
var err error
route, err = router.New(ctx)
if err != nil {
return fmt.Errorf("error creating maintenance router: %w", err)
}
// Route maintenance handlers.
maintenance := web.NewMaintenance()
maintenance.Route(route)
// Start the maintenance router to handle reqs
// while the instance is starting up / migrating.
if err := route.Start(); err != nil {
return fmt.Errorf("error starting maintenance router: %w", err)
}
// Initialize tracing (noop if not enabled).
if err := tracing.Initialize(); err != nil {
return fmt.Errorf("error initializing tracing: %w", err)
@ -359,9 +406,15 @@ var Start action.GTSAction = func(ctx context.Context) error {
HTTP router initialization
*/
// Close down the maintenance router.
if err := route.Stop(); err != nil {
return fmt.Errorf("error stopping maintenance router: %w", err)
}
// Instantiate the main router.
route, err = router.New(ctx)
if err != nil {
return fmt.Errorf("error creating router: %s", err)
return fmt.Errorf("error creating main router: %s", err)
}
// Start preparing middleware stack.

View file

@ -41,5 +41,19 @@ func serverCommands() *cobra.Command {
}
config.AddServerFlags(serverStartCmd)
serverCmd.AddCommand(serverStartCmd)
serverMaintenanceCmd := &cobra.Command{
Use: "maintenance",
Short: "start the gotosocial server in maintenance mode (returns 503 for almost all requests)",
PreRunE: func(cmd *cobra.Command, args []string) error {
return preRun(preRunArgs{cmd: cmd})
},
RunE: func(cmd *cobra.Command, args []string) error {
return run(cmd.Context(), server.Maintenance)
},
}
config.AddServerFlags(serverMaintenanceCmd)
serverCmd.AddCommand(serverMaintenanceCmd)
return serverCmd
}