about summary refs log tree commit diff
path: root/main.go
diff options
context:
space:
mode:
authorV <v@anomalous.eu>2021-08-14 08:06:03 +0200
committerV <v@anomalous.eu>2021-08-14 16:59:02 +0200
commit6c8cd3cab8e1eb9f43444b2bfbbacc66b6d9e604 (patch)
treea8d748649f799b08ec35df4836ebc928ea75d43a /main.go
parent5b28e02783c9048305ba651c6d9b843368534410 (diff)
downloadcgiserver-6c8cd3cab8e1eb9f43444b2bfbbacc66b6d9e604.tar.zst
[WIP] switch to x/sync/errgroup for exit rendezvous
Diffstat (limited to 'main.go')
-rw-r--r--main.go45
1 files changed, 31 insertions, 14 deletions
diff --git a/main.go b/main.go
index 2019888..3da87b6 100644
--- a/main.go
+++ b/main.go
@@ -8,6 +8,7 @@ import (
 	"flag"
 	"fmt"
 	"log"
+	"net"
 	"net/http"
 	"net/http/cgi"
 	"os"
@@ -16,6 +17,7 @@ import (
 
 	"github.com/coreos/go-systemd/v22/activation"
 	"github.com/gorilla/handlers"
+	"golang.org/x/sync/errgroup"
 )
 
 func main() {
@@ -62,31 +64,46 @@ func main() {
 	// Additionally, we want to log requests.
 	handler = handlers.CombinedLoggingHandler(os.Stdout, handler)
 
-	// Catch SIGTERM so we can shutdown gracefully.
-	sig := make(chan os.Signal, 1)
-	signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
-
 	// Create a Server so we can call Shutdown() on it later.
 	srv := &http.Server{Handler: handler}
 
-	doom := make(chan error)
+	// TODO(V): comment
+	ctx, cancel := context.WithCancel(context.Background())
+	group, ctx := errgroup.WithContext(ctx)
+	srv.BaseContext = func(net.Listener) context.Context { return ctx }
+
+	group.Go(func() error {
+		// Catch SIGTERM so we can shutdown gracefully.
+		sig := make(chan os.Signal, 1)
+		signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
+
+		select {
+		case <-sig:
+			log.Print("Caught signal, shutting down")
+			cancel()
+		case <-ctx.Done():
+			// Nothing to do here
+		}
+
+		return nil
+	})
+
 	for _, ln := range lns {
 		// Loop variables are unsafe to close over with goroutines,
 		// so this just shadows it with a fresh binding.
 		ln := ln
 
-		go func() {
-			// If any one of these return, it's game over.
-			doom <- srv.Serve(ln)
-		}()
+		group.Go(func() error {
+			err := srv.Serve(ln)
+			if err != http.ErrServerClosed {
+				return err
+			}
+			return nil
+		})
 	}
 
-	select {
-	case err = <-doom:
-		// Only the first error matters, the rest will be ErrServerClosed.
+	if err := group.Wait(); err != nil {
 		log.Printf("Fatal server error: %v", err)
-	case <-sig:
-		log.Print("Caught signal, shutting down")
 	}
 
 	// This will block until all existing connections are handled.