faas/gateway/handlers/probe_handler.go
Alex Ellis (OpenFaaS Ltd) 88eea5f62e Feature for probing functions
Introduces a single-flight call to a function's health
endpoint to verify that it is registered with an Istio
sidecar (Envoy) before letting the invocation through.

Results are cached for 5 seconds, before a probe is
required again.

Tested without Istio, with probe_functions environment
variable set to true, I saw a probe execute in the logs.

Fixes: #1721 for Istio users.

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alex@openfaas.com>
2022-07-07 10:35:07 +01:00

46 lines
1.2 KiB
Go

package handlers
import (
"fmt"
"net/http"
"golang.org/x/sync/singleflight"
"github.com/openfaas/faas/gateway/pkg/middleware"
"github.com/openfaas/faas/gateway/probing"
)
func MakeProbeHandler(prober probing.FunctionProber, cache probing.ProbeCacher, resolver middleware.BaseURLResolver, next http.HandlerFunc, defaultNamespace string) http.HandlerFunc {
group := singleflight.Group{}
return func(w http.ResponseWriter, r *http.Request) {
functionName, namespace := middleware.GetNamespace(defaultNamespace, middleware.GetServiceName(r.URL.String()))
key := fmt.Sprintf("Probe-%s.%s", functionName, namespace)
res, _, _ := group.Do(key, func() (interface{}, error) {
cached, hit := cache.Get(functionName, namespace)
var probeResult probing.FunctionProbeResult
if hit && cached != nil && cached.Available {
probeResult = *cached
} else {
probeResult = prober.Probe(functionName, namespace)
cache.Set(functionName, namespace, &probeResult)
}
return probeResult, nil
})
fnRes := res.(probing.FunctionProbeResult)
if !fnRes.Available {
http.Error(w, fmt.Sprintf("unable to probe function endpoint %s", fnRes.Error),
http.StatusServiceUnavailable)
return
}
next(w, r)
}
}