66 lines
1.5 KiB
Go
66 lines
1.5 KiB
Go
// Path: Backend/internal/process/process.go
|
|
|
|
package process
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log/slog"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
func RunHTTPServer(serviceName, address string, handler http.Handler, logger *slog.Logger, shutdownTimeout time.Duration) error {
|
|
server := &http.Server{
|
|
Addr: address,
|
|
Handler: handler,
|
|
ReadHeaderTimeout: 5 * time.Second,
|
|
}
|
|
|
|
serverErr := make(chan error, 1)
|
|
|
|
go func() {
|
|
logger.Info("http server starting", "service", serviceName, "address", address)
|
|
serverErr <- server.ListenAndServe()
|
|
}()
|
|
|
|
signalCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
|
|
select {
|
|
case err := <-serverErr:
|
|
if err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
return err
|
|
}
|
|
return nil
|
|
case <-signalCtx.Done():
|
|
logger.Info("shutdown requested", "service", serviceName)
|
|
}
|
|
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
|
defer cancel()
|
|
|
|
if err := server.Shutdown(shutdownCtx); err != nil {
|
|
return fmt.Errorf("shutdown %s server: %w", serviceName, err)
|
|
}
|
|
|
|
logger.Info("http server stopped", "service", serviceName)
|
|
|
|
return nil
|
|
}
|
|
|
|
func WaitForShutdown(serviceName string, logger *slog.Logger) error {
|
|
signalCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
|
|
logger.Info("process running", "service", serviceName)
|
|
<-signalCtx.Done()
|
|
logger.Info("shutdown requested", "service", serviceName)
|
|
|
|
return nil
|
|
}
|