Skip to content

Commit 105470d

Browse files
authored
feat: add health liveness and readiness endpoints to go buildpack (#34)
This commit adds `/health/readiness` and `/health/liveness` endpoints to the Go buildpack for both HTTP and CloudEvent functions. See: knative/func#169 Signed-off-by: Lance Ball <[email protected]>
1 parent 77e684f commit 105470d

File tree

1 file changed

+53
-39
lines changed

1 file changed

+53
-39
lines changed

buildpacks/go/faas/main.go

+53-39
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"context"
5+
"encoding/json"
56
"flag"
67
"fmt"
78
"net/http"
@@ -11,6 +12,8 @@ import (
1112
"syscall"
1213
"time"
1314

15+
"github.com/gorilla/mux"
16+
1417
cloudevents "github.com/cloudevents/sdk-go/v2"
1518

1619
function "function"
@@ -47,58 +50,69 @@ func run() error {
4750
cancel()
4851
}()
4952

50-
var handler interface{} = function.Handle
53+
// Use a gorilla mux for handling all HTTP requests
54+
router := mux.NewRouter()
5155

52-
httpHandler := toHttpHandler(handler, ctx)
56+
// Add handlers for readiness and liveness endpoints
57+
router.HandleFunc("/health/{endpoint:readiness|liveness}", func(w http.ResponseWriter, r *http.Request) {
58+
json.NewEncoder(w).Encode(map[string]bool{"ok": true})
59+
})
5360

54-
if httpHandler != nil {
55-
httpServer := &http.Server{
56-
Addr: fmt.Sprintf(":%d", *port),
57-
Handler: httpHandler,
58-
ReadTimeout: 1 * time.Minute,
59-
WriteTimeout: 1 * time.Minute,
60-
MaxHeaderBytes: 1 << 20,
61-
}
61+
var handler interface{} = function.Handle
6262

63-
listenAndServeErr := make(chan error, 1)
64-
go func() {
65-
if *verbose {
66-
fmt.Printf("listening on http port %v for HTTP requests\n", *port)
67-
}
68-
err := httpServer.ListenAndServe()
69-
cancel()
70-
listenAndServeErr <- err
71-
}()
72-
73-
<- ctx.Done()
74-
shutdownCtx, shutdownCancelFn := context.WithTimeout(context.Background(), time.Second * 5)
75-
defer shutdownCancelFn()
76-
err := httpServer.Shutdown(shutdownCtx)
77-
if err != nil {
78-
fmt.Fprintf(os.Stderr, "error on server shutdown: %v\n", err)
79-
}
63+
httpHandler := toHttpHandler(handler, ctx)
8064

81-
err = <-listenAndServeErr
82-
if http.ErrServerClosed == err {
83-
return nil
65+
if httpHandler == nil {
66+
if *verbose {
67+
fmt.Printf("Initializing CloudEvent function\n")
8468
}
85-
return err
86-
} else {
87-
transport, err := cloudevents.NewHTTP(
69+
protocol, err := cloudevents.NewHTTP(
8870
cloudevents.WithPort(*port),
89-
cloudevents.WithPath("/"))
71+
cloudevents.WithPath("/"),
72+
)
9073
if err != nil {
9174
return err
9275
}
93-
client, err := cloudevents.NewClient(transport)
94-
if err != nil {
95-
return err
76+
eventHandler, err := cloudevents.NewHTTPReceiveHandler(ctx, protocol, handler)
77+
router.Handle("/", eventHandler)
78+
} else {
79+
if *verbose {
80+
fmt.Printf("Initializing HTTP function\n")
9681
}
82+
router.Handle("/", httpHandler)
83+
}
84+
85+
httpServer := &http.Server{
86+
Addr: fmt.Sprintf(":%d", *port),
87+
Handler: router,
88+
ReadTimeout: 1 * time.Minute,
89+
WriteTimeout: 1 * time.Minute,
90+
MaxHeaderBytes: 1 << 20,
91+
}
92+
93+
listenAndServeErr := make(chan error, 1)
94+
go func() {
9795
if *verbose {
98-
fmt.Printf("listening on http port %v for JSON-encoded CloudEvents\n", *port)
96+
fmt.Printf("listening on http port %v\n", *port)
9997
}
100-
return client.StartReceiver(ctx, handler)
98+
err := httpServer.ListenAndServe()
99+
cancel()
100+
listenAndServeErr <- err
101+
}()
102+
103+
<-ctx.Done()
104+
shutdownCtx, shutdownCancelFn := context.WithTimeout(context.Background(), time.Second*5)
105+
defer shutdownCancelFn()
106+
err := httpServer.Shutdown(shutdownCtx)
107+
if err != nil {
108+
fmt.Fprintf(os.Stderr, "error on server shutdown: %v\n", err)
109+
}
110+
111+
err = <-listenAndServeErr
112+
if http.ErrServerClosed == err {
113+
return nil
101114
}
115+
return err
102116
}
103117

104118
// if the handler signature is compatible with http handler the function returns an instance of `http.Handler`,

0 commit comments

Comments
 (0)