From 79380f5c246123f6f909291693d846034d1a82cd Mon Sep 17 00:00:00 2001 From: Balakrishnan Balasubramanian Date: Fri, 24 Jan 2025 22:36:22 -0500 Subject: [PATCH] Support unix sockets and systemd sockets using anyhttp --- go.mod | 1 + go.sum | 6 ++++++ pkg/cli/cli.go | 48 +++++++++++++++++++++++++----------------- pkg/command/options.go | 1 + 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 0d07ccc..a237ff9 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.3 github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948 + go.balki.me/anyhttp v0.5.0 golang.org/x/crypto v0.9.0 ) diff --git a/go.sum b/go.sum index c27c81e..2bc8093 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,7 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -42,6 +43,7 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -113,6 +115,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +go.balki.me/anyhttp v0.5.0 h1:uys0oRciBpZfwtxXAevScKy6amIQBXyDrcV0EtGF5zo= +go.balki.me/anyhttp v0.5.0/go.mod h1:JhfekOIjgVODoVqUCficjpIgmB3wwlB7jhN0eN2EZ/s= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -134,6 +138,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -144,6 +149,7 @@ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cn google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go index 9ac45c5..44bf6b6 100644 --- a/pkg/cli/cli.go +++ b/pkg/cli/cli.go @@ -1,6 +1,7 @@ package cli import ( + "context" "errors" "fmt" "os" @@ -22,6 +23,7 @@ import ( "github.com/sosedoff/pgweb/pkg/metrics" "github.com/sosedoff/pgweb/pkg/queries" "github.com/sosedoff/pgweb/pkg/util" + "go.balki.me/anyhttp" ) var ( @@ -194,7 +196,7 @@ func printVersion() { fmt.Println(command.VersionString()) } -func startServer() { +func startServer() *anyhttp.ServerCtx { router := gin.New() router.Use(api.RequestLogger(logger)) router.Use(gin.Recovery()) @@ -210,18 +212,22 @@ func startServer() { api.SetupMetrics(router) fmt.Println("Starting server...") - go func() { - metrics.SetHealthy(true) + address := fmt.Sprintf("%v:%v", options.HTTPHost, options.HTTPPort) + if options.HTTPAddr != "" { + address = options.HTTPAddr + } - err := router.Run(fmt.Sprintf("%v:%v", options.HTTPHost, options.HTTPPort)) - if err != nil { - fmt.Println("Can't start server:", err) - if strings.Contains(err.Error(), "address already in use") { - openPage() - } - os.Exit(1) + metrics.SetHealthy(true) + + ctx, err := anyhttp.Serve(address, router.Handler()) + if err != nil { + fmt.Println("Can't start server:", err) + if strings.Contains(err.Error(), "address already in use") { + openPage() } - }() + os.Exit(1) + } + return ctx } func startMetricsServer() { @@ -236,12 +242,6 @@ func startMetricsServer() { } } -func handleSignals() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) - <-c -} - func openPage() { url := fmt.Sprintf("http://%v:%v/%s", options.HTTPHost, options.HTTPPort, options.Prefix) fmt.Println("To view database open", url, "in browser") @@ -327,7 +327,17 @@ func Run() { go startMetricsServer() } - startServer() + serverCtx := startServer() + openPage() - handleSignals() + + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + select { + case doneErr := <-serverCtx.Done: + logger.Infoln("idle server. shutting down error: ", doneErr) + case <-c: + logger.Infoln("received signal. shutting down") + serverCtx.Shutdown(context.TODO()) + } } diff --git a/pkg/command/options.go b/pkg/command/options.go index 0088a8b..24df4c6 100644 --- a/pkg/command/options.go +++ b/pkg/command/options.go @@ -39,6 +39,7 @@ type Options struct { OpenTimeout int `long:"open-timeout" description:"Maximum wait time for connection, in seconds" default:"30"` RetryDelay uint `long:"open-retry-delay" description:"Number of seconds to wait before retrying the connection" default:"3"` RetryCount uint `long:"open-retry" description:"Number of times to retry establishing connection" default:"0"` + HTTPAddr string `long:"address" description:"anyhttp address. See https://pkg.go.dev/go.balki.me/anyhttp#readme-address-syntax" default:""` HTTPHost string `long:"bind" description:"HTTP server host" default:"localhost"` HTTPPort uint `long:"listen" description:"HTTP server listen port" default:"8081"` AuthUser string `long:"auth-user" description:"HTTP basic auth user"`