faas/gateway/handlers/scaling.go
Alex Ellis (OpenFaaS Ltd) df4126d8f5 Scale functions with namespace option
Allows alerts to trigger functions to scale when they
also have an optional namespace set.

Tested e2e with Kubernetes 1.15 and a non-default namespace.

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-09-20 18:38:55 +01:00

64 lines
1.8 KiB
Go

// Copyright (c) OpenFaaS Author(s). All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
package handlers
import (
"fmt"
"log"
"net/http"
"strings"
"github.com/openfaas/faas/gateway/scaling"
)
func getNamespace(defaultNamespace, fullName string) (string, string) {
if index := strings.LastIndex(fullName, "."); index > -1 {
return fullName[:index], fullName[index+1:]
}
return fullName, defaultNamespace
}
// MakeScalingHandler creates handler which can scale a function from
// zero to N replica(s). After scaling the next http.HandlerFunc will
// be called. If the function is not ready after the configured
// amount of attempts / queries then next will not be invoked and a status
// will be returned to the client.
func MakeScalingHandler(next http.HandlerFunc, config scaling.ScalingConfig, defaultNamespace string) http.HandlerFunc {
scaler := scaling.NewFunctionScaler(config)
return func(w http.ResponseWriter, r *http.Request) {
functionName := getServiceName(r.URL.String())
_, namespace := getNamespace(defaultNamespace, functionName)
res := scaler.Scale(functionName, namespace)
if !res.Found {
errStr := fmt.Sprintf("error finding function %s: %s", functionName, res.Error.Error())
log.Printf("Scaling: %s", errStr)
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(errStr))
return
}
if res.Error != nil {
errStr := fmt.Sprintf("error finding function %s: %s", functionName, res.Error.Error())
log.Printf("Scaling: %s", errStr)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(errStr))
return
}
if res.Available {
next.ServeHTTP(w, r)
return
}
log.Printf("[Scale] function=%s 0=>N timed-out after %f seconds", functionName, res.Duration.Seconds())
}
}