diff --git a/template/golang-http-armhf/.gitignore b/template/golang-http-armhf/.gitignore new file mode 100644 index 0000000..8915b60 --- /dev/null +++ b/template/golang-http-armhf/.gitignore @@ -0,0 +1 @@ +/handler diff --git a/template/golang-http-armhf/Dockerfile b/template/golang-http-armhf/Dockerfile index d0b2234..5edb1ad 100644 --- a/template/golang-http-armhf/Dockerfile +++ b/template/golang-http-armhf/Dockerfile @@ -1,4 +1,4 @@ -FROM openfaas/of-watchdog:0.7.3 as watchdog +FROM openfaas/of-watchdog:0.7.6 as watchdog FROM golang:1.13-alpine3.11 as build RUN apk --no-cache add git diff --git a/template/golang-http-armhf/main.go b/template/golang-http-armhf/main.go index d023f30..2363a39 100644 --- a/template/golang-http-armhf/main.go +++ b/template/golang-http-armhf/main.go @@ -1,19 +1,80 @@ package main import ( + "context" "fmt" "io/ioutil" "log" "net/http" "os" + "os/signal" "strconv" + "sync/atomic" + "syscall" "time" "handler/function" - // "github.com/alexellis/golang-http-template/template/golang-http/function" + handler "github.com/openfaas-incubator/go-function-sdk" ) +var ( + acceptingConnections int32 +) + +const defaultTimeout = 10 * time.Second + +func main() { + readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), defaultTimeout) + writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), defaultTimeout) + + s := &http.Server{ + Addr: fmt.Sprintf(":%d", 8082), + ReadTimeout: readTimeout, + WriteTimeout: writeTimeout, + MaxHeaderBytes: 1 << 20, // Max header of 1MB + } + + http.HandleFunc("/", makeRequestHandler()) + listenUntilShutdown(s, writeTimeout) +} + +func listenUntilShutdown(s *http.Server, shutdownTimeout time.Duration) { + idleConnsClosed := make(chan struct{}) + go func() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGTERM) + + <-sig + + log.Printf("[entrypoint] SIGTERM received.. shutting down server in %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + if err := s.Shutdown(context.Background()); err != nil { + log.Printf("[entrypoint] Error in Shutdown: %v", err) + } + + log.Printf("[entrypoint] No new connections allowed. Exiting in: %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + close(idleConnsClosed) + }() + + // Run the HTTP server in a separate go-routine. + go func() { + if err := s.ListenAndServe(); err != http.ErrServerClosed { + log.Printf("[entrypoint] Error ListenAndServe: %v", err) + close(idleConnsClosed) + } + }() + + atomic.StoreInt32(&acceptingConnections, 1) + + <-idleConnsClosed +} + func makeRequestHandler() func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var input []byte @@ -74,18 +135,3 @@ func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { } return duration } - -func main() { - readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), 10*time.Second) - writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), 10*time.Second) - - s := &http.Server{ - Addr: fmt.Sprintf(":%d", 8082), - ReadTimeout: readTimeout, - WriteTimeout: writeTimeout, - MaxHeaderBytes: 1 << 20, // Max header of 1MB - } - - http.HandleFunc("/", makeRequestHandler()) - log.Fatal(s.ListenAndServe()) -} diff --git a/template/golang-http/.gitignore b/template/golang-http/.gitignore new file mode 100644 index 0000000..8915b60 --- /dev/null +++ b/template/golang-http/.gitignore @@ -0,0 +1 @@ +/handler diff --git a/template/golang-http/Dockerfile b/template/golang-http/Dockerfile index fe2017a..b0c2637 100644 --- a/template/golang-http/Dockerfile +++ b/template/golang-http/Dockerfile @@ -1,4 +1,4 @@ -FROM openfaas/of-watchdog:0.7.3 as watchdog +FROM openfaas/of-watchdog:0.7.6 as watchdog FROM golang:1.13-alpine3.11 as build RUN apk --no-cache add git diff --git a/template/golang-http/main.go b/template/golang-http/main.go index d023f30..2363a39 100644 --- a/template/golang-http/main.go +++ b/template/golang-http/main.go @@ -1,19 +1,80 @@ package main import ( + "context" "fmt" "io/ioutil" "log" "net/http" "os" + "os/signal" "strconv" + "sync/atomic" + "syscall" "time" "handler/function" - // "github.com/alexellis/golang-http-template/template/golang-http/function" + handler "github.com/openfaas-incubator/go-function-sdk" ) +var ( + acceptingConnections int32 +) + +const defaultTimeout = 10 * time.Second + +func main() { + readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), defaultTimeout) + writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), defaultTimeout) + + s := &http.Server{ + Addr: fmt.Sprintf(":%d", 8082), + ReadTimeout: readTimeout, + WriteTimeout: writeTimeout, + MaxHeaderBytes: 1 << 20, // Max header of 1MB + } + + http.HandleFunc("/", makeRequestHandler()) + listenUntilShutdown(s, writeTimeout) +} + +func listenUntilShutdown(s *http.Server, shutdownTimeout time.Duration) { + idleConnsClosed := make(chan struct{}) + go func() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGTERM) + + <-sig + + log.Printf("[entrypoint] SIGTERM received.. shutting down server in %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + if err := s.Shutdown(context.Background()); err != nil { + log.Printf("[entrypoint] Error in Shutdown: %v", err) + } + + log.Printf("[entrypoint] No new connections allowed. Exiting in: %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + close(idleConnsClosed) + }() + + // Run the HTTP server in a separate go-routine. + go func() { + if err := s.ListenAndServe(); err != http.ErrServerClosed { + log.Printf("[entrypoint] Error ListenAndServe: %v", err) + close(idleConnsClosed) + } + }() + + atomic.StoreInt32(&acceptingConnections, 1) + + <-idleConnsClosed +} + func makeRequestHandler() func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var input []byte @@ -74,18 +135,3 @@ func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { } return duration } - -func main() { - readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), 10*time.Second) - writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), 10*time.Second) - - s := &http.Server{ - Addr: fmt.Sprintf(":%d", 8082), - ReadTimeout: readTimeout, - WriteTimeout: writeTimeout, - MaxHeaderBytes: 1 << 20, // Max header of 1MB - } - - http.HandleFunc("/", makeRequestHandler()) - log.Fatal(s.ListenAndServe()) -} diff --git a/template/golang-middleware-armhf/.gitignore b/template/golang-middleware-armhf/.gitignore new file mode 100644 index 0000000..8915b60 --- /dev/null +++ b/template/golang-middleware-armhf/.gitignore @@ -0,0 +1 @@ +/handler diff --git a/template/golang-middleware-armhf/Dockerfile b/template/golang-middleware-armhf/Dockerfile index d0b2234..5edb1ad 100644 --- a/template/golang-middleware-armhf/Dockerfile +++ b/template/golang-middleware-armhf/Dockerfile @@ -1,4 +1,4 @@ -FROM openfaas/of-watchdog:0.7.3 as watchdog +FROM openfaas/of-watchdog:0.7.6 as watchdog FROM golang:1.13-alpine3.11 as build RUN apk --no-cache add git diff --git a/template/golang-middleware-armhf/main.go b/template/golang-middleware-armhf/main.go index e8afc47..1d49220 100644 --- a/template/golang-middleware-armhf/main.go +++ b/template/golang-middleware-armhf/main.go @@ -1,17 +1,78 @@ package main import ( + "context" "fmt" "log" "net/http" "os" + "os/signal" "strconv" + "sync/atomic" + "syscall" "time" "handler/function" - //"github.com/openfaas-incubator/golang-http-template/template/golang-middleware/function" ) +var ( + acceptingConnections int32 +) + +const defaultTimeout = 10 * time.Second + +func main() { + readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), defaultTimeout) + writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), defaultTimeout) + + s := &http.Server{ + Addr: fmt.Sprintf(":%d", 8082), + ReadTimeout: readTimeout, + WriteTimeout: writeTimeout, + MaxHeaderBytes: 1 << 20, // Max header of 1MB + } + + http.HandleFunc("/", function.Handle) + + listenUntilShutdown(s, writeTimeout) +} + +func listenUntilShutdown(s *http.Server, shutdownTimeout time.Duration) { + idleConnsClosed := make(chan struct{}) + go func() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGTERM) + + <-sig + + log.Printf("[entrypoint] SIGTERM received.. shutting down server in %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + if err := s.Shutdown(context.Background()); err != nil { + log.Printf("[entrypoint] Error in Shutdown: %v", err) + } + + log.Printf("[entrypoint] No new connections allowed. Exiting in: %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + close(idleConnsClosed) + }() + + // Run the HTTP server in a separate go-routine. + go func() { + if err := s.ListenAndServe(); err != http.ErrServerClosed { + log.Printf("[entrypoint] Error ListenAndServe: %v", err) + close(idleConnsClosed) + } + }() + + atomic.StoreInt32(&acceptingConnections, 1) + + <-idleConnsClosed +} + func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { if len(val) > 0 { parsedVal, parseErr := strconv.Atoi(val) @@ -26,18 +87,3 @@ func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { } return duration } - -func main() { - readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), 10*time.Second) - writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), 10*time.Second) - - s := &http.Server{ - Addr: fmt.Sprintf(":%d", 8082), - ReadTimeout: readTimeout, - WriteTimeout: writeTimeout, - MaxHeaderBytes: 1 << 20, // Max header of 1MB - } - - http.HandleFunc("/", function.Handle) - log.Fatal(s.ListenAndServe()) -} diff --git a/template/golang-middleware/.gitignore b/template/golang-middleware/.gitignore new file mode 100644 index 0000000..8915b60 --- /dev/null +++ b/template/golang-middleware/.gitignore @@ -0,0 +1 @@ +/handler diff --git a/template/golang-middleware/Dockerfile b/template/golang-middleware/Dockerfile index 694be1d..6f76ca2 100644 --- a/template/golang-middleware/Dockerfile +++ b/template/golang-middleware/Dockerfile @@ -1,4 +1,4 @@ -FROM openfaas/of-watchdog:0.7.3 as watchdog +FROM openfaas/of-watchdog:0.7.6 as watchdog FROM golang:1.13-alpine3.11 as build RUN apk --no-cache add git diff --git a/template/golang-middleware/main.go b/template/golang-middleware/main.go index e8afc47..1d49220 100644 --- a/template/golang-middleware/main.go +++ b/template/golang-middleware/main.go @@ -1,17 +1,78 @@ package main import ( + "context" "fmt" "log" "net/http" "os" + "os/signal" "strconv" + "sync/atomic" + "syscall" "time" "handler/function" - //"github.com/openfaas-incubator/golang-http-template/template/golang-middleware/function" ) +var ( + acceptingConnections int32 +) + +const defaultTimeout = 10 * time.Second + +func main() { + readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), defaultTimeout) + writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), defaultTimeout) + + s := &http.Server{ + Addr: fmt.Sprintf(":%d", 8082), + ReadTimeout: readTimeout, + WriteTimeout: writeTimeout, + MaxHeaderBytes: 1 << 20, // Max header of 1MB + } + + http.HandleFunc("/", function.Handle) + + listenUntilShutdown(s, writeTimeout) +} + +func listenUntilShutdown(s *http.Server, shutdownTimeout time.Duration) { + idleConnsClosed := make(chan struct{}) + go func() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGTERM) + + <-sig + + log.Printf("[entrypoint] SIGTERM received.. shutting down server in %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + if err := s.Shutdown(context.Background()); err != nil { + log.Printf("[entrypoint] Error in Shutdown: %v", err) + } + + log.Printf("[entrypoint] No new connections allowed. Exiting in: %s\n", shutdownTimeout.String()) + + <-time.Tick(shutdownTimeout) + + close(idleConnsClosed) + }() + + // Run the HTTP server in a separate go-routine. + go func() { + if err := s.ListenAndServe(); err != http.ErrServerClosed { + log.Printf("[entrypoint] Error ListenAndServe: %v", err) + close(idleConnsClosed) + } + }() + + atomic.StoreInt32(&acceptingConnections, 1) + + <-idleConnsClosed +} + func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { if len(val) > 0 { parsedVal, parseErr := strconv.Atoi(val) @@ -26,18 +87,3 @@ func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration { } return duration } - -func main() { - readTimeout := parseIntOrDurationValue(os.Getenv("read_timeout"), 10*time.Second) - writeTimeout := parseIntOrDurationValue(os.Getenv("write_timeout"), 10*time.Second) - - s := &http.Server{ - Addr: fmt.Sprintf(":%d", 8082), - ReadTimeout: readTimeout, - WriteTimeout: writeTimeout, - MaxHeaderBytes: 1 << 20, // Max header of 1MB - } - - http.HandleFunc("/", function.Handle) - log.Fatal(s.ListenAndServe()) -}