// Package grpcshutdown centralizes gRPC draining semantics for all services. package grpcshutdown import ( "time" "google.golang.org/grpc" ) const defaultTimeout = 15 * time.Second // GracefulStop waits for in-flight RPCs to finish, then falls back to Stop so a // wedged client stream cannot block deploy shutdown forever. func GracefulStop(server *grpc.Server, timeout time.Duration) { if server == nil { return } if timeout <= 0 { timeout = defaultTimeout } done := make(chan struct{}) go func() { server.GracefulStop() close(done) }() select { case <-done: case <-time.After(timeout): server.Stop() <-done } }