Files
SciMesh/users/internal/infra/server.go
T
Efremenko Arhip 0c1f5f06d4 chore(users): remove coordinator leftovers, tidy for userservice
- delete api/requests.http and ARCHITECTURE.md (coordinator content)
- rewrite README.md and .env.example for the userservice
- drop dead RunPeriodic (reaper machinery userservice has no use for)
- fix .gitignore/.dockerignore/.golangci.yml module + artifact names
- degeneralize stale copied comments that said "coordinator"
2026-07-26 16:36:17 +03:00

45 lines
1.2 KiB
Go

// Server: the HTTP listener, shut down cleanly on a signal.
package infra
import (
"context"
"errors"
"log/slog"
"net/http"
"time"
)
const shutdownGrace = 15 * time.Second
// RunServer serves handler until ctx is cancelled, then drains in-flight requests.
func RunServer(ctx context.Context, log *slog.Logger, addr string, handler http.Handler) error {
srv := &http.Server{
Addr: addr,
Handler: handler,
ReadHeaderTimeout: 5 * time.Second,
}
// Buffered so this goroutine can exit even when nobody reads the channel
// (the ctx.Done branch below) — an unbuffered send would leak it forever.
errCh := make(chan error, 1)
go func() {
log.Info("userservice listening", "addr", addr)
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
errCh <- err
}
}()
select {
case err := <-errCh:
return err
case <-ctx.Done():
log.Info("shutdown signal received")
}
// A fresh context: ctx is already cancelled, and reusing it would abort the
// very requests we are trying to let finish.
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownGrace)
defer cancel()
return srv.Shutdown(shutdownCtx)
}