gracefully shutdown on sigint/sigterm
This commit is contained in:
parent
9c3ea8dd80
commit
8ebf4a26f4
@ -2,14 +2,20 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/emersion/go-sasl"
|
||||
"github.com/mediocregopher/blog.mediocregopher.com/srv/mailinglist"
|
||||
@ -25,10 +31,17 @@ func loggerFatalErr(ctx context.Context, logger *mlog.Logger, descr string, err
|
||||
|
||||
func main() {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
logger := mlog.NewLogger(nil)
|
||||
defer logger.Close()
|
||||
|
||||
logger.Info(ctx, "process started")
|
||||
defer logger.Info(ctx, "process exiting")
|
||||
|
||||
publicURLStr := flag.String("public-url", "http://localhost:4000", "URL this service is accessible at")
|
||||
listenAddr := flag.String("listen-addr", ":4000", "Address to listen for HTTP requests on")
|
||||
listenProto := flag.String("listen-proto", "tcp", "Protocol to listen for HTTP requests with")
|
||||
listenAddr := flag.String("listen-addr", ":4000", "Address/path to listen for HTTP requests on")
|
||||
dataDir := flag.String("data-dir", ".", "Directory to use for long term storage")
|
||||
|
||||
staticDir := flag.String("static-dir", "", "Directory from which static files are served (mutually exclusive with -static-proxy-url)")
|
||||
@ -46,45 +59,46 @@ func main() {
|
||||
|
||||
switch {
|
||||
case *staticDir == "" && *staticProxyURLStr == "":
|
||||
logger.Fatal(context.Background(), "-static-dir or -static-proxy-url is required")
|
||||
logger.Fatal(ctx, "-static-dir or -static-proxy-url is required")
|
||||
case *powSecret == "":
|
||||
logger.Fatal(context.Background(), "-pow-secret is required")
|
||||
logger.Fatal(ctx, "-pow-secret is required")
|
||||
case *smtpAddr == "":
|
||||
logger.Fatal(context.Background(), "-ml-smtp-addr is required")
|
||||
logger.Fatal(ctx, "-ml-smtp-addr is required")
|
||||
case *smtpAuthStr == "":
|
||||
logger.Fatal(context.Background(), "-ml-smtp-auth is required")
|
||||
logger.Fatal(ctx, "-ml-smtp-auth is required")
|
||||
}
|
||||
|
||||
publicURL, err := url.Parse(*publicURLStr)
|
||||
if err != nil {
|
||||
loggerFatalErr(context.Background(), logger, "parsing -public-url", err)
|
||||
loggerFatalErr(ctx, logger, "parsing -public-url", err)
|
||||
}
|
||||
|
||||
var staticProxyURL *url.URL
|
||||
if *staticProxyURLStr != "" {
|
||||
var err error
|
||||
if staticProxyURL, err = url.Parse(*staticProxyURLStr); err != nil {
|
||||
loggerFatalErr(context.Background(), logger, "parsing -static-proxy-url", err)
|
||||
loggerFatalErr(ctx, logger, "parsing -static-proxy-url", err)
|
||||
}
|
||||
}
|
||||
|
||||
powTargetUint, err := strconv.ParseUint(*powTargetStr, 0, 32)
|
||||
if err != nil {
|
||||
loggerFatalErr(context.Background(), logger, "parsing -pow-target", err)
|
||||
loggerFatalErr(ctx, logger, "parsing -pow-target", err)
|
||||
}
|
||||
powTarget := uint32(powTargetUint)
|
||||
|
||||
smtpAuthParts := strings.SplitN(*smtpAuthStr, ":", 2)
|
||||
if len(smtpAuthParts) < 2 {
|
||||
logger.Fatal(context.Background(), "invalid -ml-smtp-auth")
|
||||
logger.Fatal(ctx, "invalid -ml-smtp-auth")
|
||||
}
|
||||
smtpAuth := sasl.NewPlainClient("", smtpAuthParts[0], smtpAuthParts[1])
|
||||
smtpSendAs := smtpAuthParts[0]
|
||||
|
||||
// initialization
|
||||
|
||||
ctx := mctx.Annotate(context.Background(),
|
||||
ctx = mctx.Annotate(ctx,
|
||||
"publicURL", publicURL.String(),
|
||||
"listenProto", *listenProto,
|
||||
"listenAddr", *listenAddr,
|
||||
"dataDir", *dataDir,
|
||||
"powTarget", fmt.Sprintf("%x", powTarget),
|
||||
@ -164,7 +178,32 @@ func main() {
|
||||
|
||||
logger.Info(ctx, "listening")
|
||||
|
||||
// TODO graceful shutdown
|
||||
err = http.ListenAndServe(*listenAddr, mux)
|
||||
loggerFatalErr(ctx, logger, "listening", err)
|
||||
l, err := net.Listen(*listenProto, *listenAddr)
|
||||
if err != nil {
|
||||
loggerFatalErr(ctx, logger, "creating listen socket", err)
|
||||
}
|
||||
|
||||
srv := &http.Server{Handler: mux}
|
||||
go func() {
|
||||
if err := srv.Serve(l); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
loggerFatalErr(ctx, logger, "serving http server", err)
|
||||
}
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
closeCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
logger.Info(ctx, "beginning graceful shutdown of http server")
|
||||
|
||||
if err := srv.Shutdown(closeCtx); err != nil {
|
||||
loggerFatalErr(ctx, logger, "gracefully shutting down http server", err)
|
||||
}
|
||||
}()
|
||||
|
||||
sigCh := make(chan os.Signal)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigCh
|
||||
|
||||
// let the defers begin
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user