From 92cd5334ec888edc67c587a1a21f2370b172c36b Mon Sep 17 00:00:00 2001 From: Soam Vasani Date: Mon, 20 Feb 2017 23:51:06 -0800 Subject: [PATCH] Add a default handler for the / route Before this change, if the user doesn't define a route for /, the router happily 404s at that path. This breaks GKE Ingress, which uses that request as a health check. So this change adds a handler for "GET /", unless the user already has one. Also, log the delay for slow requests. --- router/functionHandler.go | 7 ++++++- router/httpTriggers.go | 21 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/router/functionHandler.go b/router/functionHandler.go index a3a807e4..8ed6ecb9 100644 --- a/router/functionHandler.go +++ b/router/functionHandler.go @@ -86,11 +86,12 @@ func (fh *functionHandler) tapService(serviceUrl *url.URL) { } err := fh.poolmgr.TapService(serviceUrl) if err != nil { - log.Printf("tap service error: %v", serviceUrl.String()) + log.Printf("tap service error for %v: %v", serviceUrl.String(), err) } } func (fh *functionHandler) handler(responseWriter http.ResponseWriter, request *http.Request) { + reqStartTime := time.Now() // cache lookup serviceUrl, err := fh.fmap.lookup(&fh.Function) @@ -150,5 +151,9 @@ func (fh *functionHandler) handler(responseWriter http.ResponseWriter, request * initalTimeout: 50 * time.Millisecond, }, } + delay := time.Now().Sub(reqStartTime) + if delay > 100*time.Millisecond { + log.Printf("Request delay for %v: %v", serviceUrl, delay) + } proxy.ServeHTTP(responseWriter, request) } diff --git a/router/httpTriggers.go b/router/httpTriggers.go index dbbae074..e8b0744f 100644 --- a/router/httpTriggers.go +++ b/router/httpTriggers.go @@ -18,6 +18,7 @@ package router import ( "log" + "net/http" "time" "github.com/gorilla/mux" @@ -52,16 +53,21 @@ func (ts *HTTPTriggerSet) subscribeRouter(mr *mutableRouter) { go ts.watchTriggers() } +func defaultHomeHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) +} + func (ts *HTTPTriggerSet) getRouter() *mux.Router { muxRouter := mux.NewRouter() - // make a name -> latest version map + // make a function name -> latest version map latestVersions := make(map[string]string) for _, f := range ts.functions { latestVersions[f.Metadata.Name] = f.Metadata.Uid } // HTTP triggers setup by the user + homeHandled := false for _, trigger := range ts.triggers { m := trigger.Function if len(m.Uid) == 0 { @@ -74,6 +80,19 @@ func (ts *HTTPTriggerSet) getRouter() *mux.Router { poolmgr: ts.poolmgr, } muxRouter.HandleFunc(trigger.UrlPattern, fh.handler).Methods(trigger.Method) + if trigger.UrlPattern == "/" && trigger.Method == "GET" { + homeHandled = true + } + } + if !homeHandled { + // + // This adds a no-op handler that returns 200-OK to make sure that the + // "GET /" request succeeds. This route is used by GKE Ingress (and + // perhaps other ingress implementations) as a health check, so we don't + // want it to be a 404 even if the user doesn't have a function mapped to + // this route. + // + muxRouter.HandleFunc("/", defaultHomeHandler).Methods("GET") } // Internal triggers for (the latest version of) each function