+48
-24
@@ -33,8 +33,8 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/satori/go.uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
@@ -51,6 +51,7 @@ const (
|
||||
|
||||
type (
|
||||
functionHandler struct {
|
||||
logger *zap.Logger
|
||||
fmap *functionServiceMap
|
||||
frmap *functionRecorderMap
|
||||
trmap *triggerRecorderMap
|
||||
@@ -86,6 +87,7 @@ type (
|
||||
|
||||
// A layer on top of http.DefaultTransport, with retries.
|
||||
RetryingRoundTripper struct {
|
||||
logger *zap.Logger
|
||||
funcHandler *functionHandler
|
||||
base http.RoundTripper
|
||||
}
|
||||
@@ -146,7 +148,7 @@ func (w *fakeCloseReadCloser) RealClose() error {
|
||||
// if it returned an error.
|
||||
func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *http.Response, err error) {
|
||||
// Set forwarded host header if not exists
|
||||
addForwardedHostHeader(req)
|
||||
roundTripper.addForwardedHostHeader(req)
|
||||
|
||||
// TODO: Keep? --> Needed for queries encoded in URL before they're stripped by the proxy
|
||||
var originalUrl url.URL
|
||||
@@ -164,7 +166,7 @@ func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *htt
|
||||
|
||||
rdr1.Read(p)
|
||||
postedBody = string(p)
|
||||
log.Info(fmt.Sprintf("%v", postedBody))
|
||||
roundTripper.logger.Info("roundtripper posted body", zap.String("body", postedBody))
|
||||
req.Body = rdr2
|
||||
}
|
||||
}
|
||||
@@ -287,13 +289,15 @@ func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *htt
|
||||
if roundTripper.funcHandler.httpTrigger != nil {
|
||||
trigger := roundTripper.funcHandler.httpTrigger.Metadata.Name
|
||||
redis.Record(
|
||||
roundTripper.logger,
|
||||
trigger,
|
||||
roundTripper.funcHandler.recorderName,
|
||||
req.Header.Get("X-Fission-ReqUID"), req, originalUrl, postedBody, resp, fnMeta.Namespace,
|
||||
time.Now().UnixNano(),
|
||||
)
|
||||
} else {
|
||||
log.Printf("No http trigger attached for recorder: %v", roundTripper.funcHandler.recorderName)
|
||||
roundTripper.logger.Error("no http trigger attached for recorder",
|
||||
zap.String("recorder", roundTripper.funcHandler.recorderName))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +307,7 @@ func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *htt
|
||||
|
||||
// if transport.RoundTrip returns a non-network dial error, then relay it back to user
|
||||
if !fission.IsNetworkDialError(err) {
|
||||
err = errors.Wrapf(err, "Error sending request to function %v", fnMeta.Name)
|
||||
err = errors.Wrapf(err, "error sending request to function %v", fnMeta.Name)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -313,8 +317,9 @@ func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *htt
|
||||
executingTimeout = executingTimeout * time.Duration(roundTripper.funcHandler.tsRoundTripperParams.timeoutExponent)
|
||||
retryCounter++
|
||||
|
||||
log.Printf("request to %s errored out. backing off for %v before retrying",
|
||||
req.URL.Host, executingTimeout)
|
||||
roundTripper.logger.Info("request errored out - backing off before retrying",
|
||||
zap.String("url", req.URL.Host),
|
||||
zap.Duration("backoff_timeout", executingTimeout))
|
||||
|
||||
time.Sleep(executingTimeout)
|
||||
|
||||
@@ -324,9 +329,9 @@ func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *htt
|
||||
} else {
|
||||
// if transport.RoundTrip returns a network dial error and serviceUrl was from cache,
|
||||
// it means, the entry in router cache is stale, so invalidate it.
|
||||
log.Printf("request to %s errored out. removing function : %s from router's cache "+
|
||||
"and requesting a new service for function",
|
||||
req.URL.Host, fnMeta.Name)
|
||||
roundTripper.logger.Error("request errored out - removing function from router's cache and requesting a new service for function",
|
||||
zap.String("url", req.URL.Host),
|
||||
zap.String("function_name", fnMeta.Name))
|
||||
roundTripper.funcHandler.fmap.remove(fnMeta)
|
||||
retryCounter = 0
|
||||
}
|
||||
@@ -340,7 +345,9 @@ func (roundTripper RetryingRoundTripper) RoundTrip(req *http.Request) (resp *htt
|
||||
// finally, one more retry with the default timeout
|
||||
resp, err = http.DefaultTransport.RoundTrip(req)
|
||||
if err != nil {
|
||||
log.Printf("Error getting response from function %v: %v", fnMeta.Name, err)
|
||||
roundTripper.logger.Error("error getting response from function",
|
||||
zap.Error(err),
|
||||
zap.String("function_name", fnMeta.Name))
|
||||
}
|
||||
|
||||
return resp, err
|
||||
@@ -385,19 +392,19 @@ func (fh functionHandler) handler(responseWriter http.ResponseWriter, request *h
|
||||
UID := strings.ToLower(uuid.NewV4().String())
|
||||
reqUID = "REQ" + UID
|
||||
request.Header.Set("X-Fission-ReqUID", reqUID)
|
||||
log.Print("Record request with ReqUID: ", reqUID)
|
||||
fh.logger.Info("record request", zap.String("request_id", reqUID))
|
||||
}
|
||||
|
||||
if fh.httpTrigger != nil && fh.httpTrigger.Spec.FunctionReference.Type == fission.FunctionReferenceTypeFunctionWeights {
|
||||
// canary deployment. need to determine the function to send request to now
|
||||
fnMetadata := getCanaryBackend(fh.functionMetadataMap, fh.fnWeightDistributionList)
|
||||
if fnMetadata == nil {
|
||||
log.Printf("Error getting canary backend ")
|
||||
fh.logger.Error("could not get canary backend", zap.String("request_id", reqUID))
|
||||
// TODO : write error to responseWrite and return response
|
||||
return
|
||||
}
|
||||
fh.function = fnMetadata
|
||||
log.Debugf("chosen fnBackend's metadata : %+v", fh.function)
|
||||
fh.logger.Debug("chosen function backend's metadata", zap.Any("metadata", fh.function))
|
||||
}
|
||||
|
||||
// system params
|
||||
@@ -413,6 +420,7 @@ func (fh functionHandler) handler(responseWriter http.ResponseWriter, request *h
|
||||
proxy := &httputil.ReverseProxy{
|
||||
Director: director,
|
||||
Transport: &RetryingRoundTripper{
|
||||
logger: fh.logger.Named("roundtripper"),
|
||||
funcHandler: &fh,
|
||||
base: &ochttp.Transport{
|
||||
Base: &http.Transport{
|
||||
@@ -471,7 +479,7 @@ func getCanaryBackend(fnMetadatamap map[string]*metav1.ObjectMeta, fnWtDistribut
|
||||
}
|
||||
|
||||
// addForwardedHostHeader add "forwarded host" to request header
|
||||
func addForwardedHostHeader(req *http.Request) {
|
||||
func (roundTripper RetryingRoundTripper) addForwardedHostHeader(req *http.Request) {
|
||||
// for more detailed information, please visit:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded
|
||||
|
||||
@@ -486,7 +494,9 @@ func addForwardedHostHeader(req *http.Request) {
|
||||
reqUrl := fmt.Sprintf("%s://%s", req.Proto, req.Host)
|
||||
u, err := url.Parse(reqUrl)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing request url (%v): %v", reqUrl, err)
|
||||
roundTripper.logger.Error("error parsing request url while adding forwarded host headers",
|
||||
zap.Error(err),
|
||||
zap.String("url", reqUrl))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -531,14 +541,19 @@ func (fh *functionHandler) getServiceEntry(ctx context.Context) (serviceUrl *url
|
||||
var u *url.URL
|
||||
// Get service entry from executor and update cache if its the first goroutine
|
||||
if firstToTheLock { // first to the service url
|
||||
log.Printf("Calling getServiceForFunction for function: %s", fh.function.Name)
|
||||
fh.logger.Info("calling getServiceForFunction",
|
||||
zap.String("function_name", fh.function.Name))
|
||||
u, err = fh.getServiceEntryFromExecutor(ctx)
|
||||
if err != nil {
|
||||
log.Printf("Error getting service url from executor: %v", err)
|
||||
fh.logger.Error("error getting service url from executor",
|
||||
zap.Error(err),
|
||||
zap.String("function_name", fh.function.Name))
|
||||
return nil, err
|
||||
}
|
||||
// add the address in router's cache
|
||||
log.Printf("Assigning service url: %s for function: %s", u, fh.function.Name)
|
||||
fh.logger.Info("assigning service url for function",
|
||||
zap.String("url", u.String()),
|
||||
zap.String("function_name", fh.function.Name))
|
||||
fh.fmap.assign(fh.function, u)
|
||||
} else {
|
||||
u, err = fh.getServiceEntryFromCache()
|
||||
@@ -554,9 +569,12 @@ func (fh *functionHandler) getServiceEntry(ctx context.Context) (serviceUrl *url
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("Error updating service address entry for function %v_%v", fh.function.Name, fh.function.Namespace))
|
||||
log.Println(err)
|
||||
return nil, false, err
|
||||
e := "error updating service address entry for function"
|
||||
fh.logger.Error(e,
|
||||
zap.Error(err),
|
||||
zap.String("function_name", fh.function.Name),
|
||||
zap.String("function_namespace", fh.function.Namespace))
|
||||
return nil, false, errors.Wrapf(err, "%s %s_%s", e, fh.function.Name, fh.function.Namespace)
|
||||
}
|
||||
|
||||
record, ok := recordObj.(svcEntryRecord)
|
||||
@@ -596,14 +614,20 @@ func (fh *functionHandler) getServiceEntryFromExecutor(ctx context.Context) (*ur
|
||||
service, err := fh.executor.GetServiceForFunction(ctx, fh.function)
|
||||
if err != nil {
|
||||
statusCode, errMsg := fission.GetHTTPError(err)
|
||||
log.Printf("Error from GetServiceForFunction for function (%v): %v : %v", fh.function, statusCode, errMsg)
|
||||
fh.logger.Error("error from GetServiceForFunction",
|
||||
zap.Error(err),
|
||||
zap.String("error_message", errMsg),
|
||||
zap.Any("function", fh.function),
|
||||
zap.Int("status_code", statusCode))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse the address into url
|
||||
serviceUrl, err := url.Parse(fmt.Sprintf("http://%v", service))
|
||||
if err != nil {
|
||||
log.Printf("Error parsing service url (%v): %v", serviceUrl, err)
|
||||
fh.logger.Error("error parsing service url",
|
||||
zap.Error(err),
|
||||
zap.String("service_url", serviceUrl.String()))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func createBackendService(testResponseString string) *url.URL {
|
||||
@@ -53,8 +55,10 @@ func TestFunctionProxying(t *testing.T) {
|
||||
log.Printf("Created backend svc at %v", backendURL)
|
||||
|
||||
fn := &metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault}
|
||||
logger, err := zap.NewDevelopment()
|
||||
panicIf(err)
|
||||
|
||||
fmap := makeFunctionServiceMap(0)
|
||||
fmap := makeFunctionServiceMap(logger, 0)
|
||||
fmap.assign(fn, backendURL)
|
||||
|
||||
httpTrigger := &crd.HTTPTrigger{
|
||||
@@ -70,7 +74,9 @@ func TestFunctionProxying(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
fh := &functionHandler{fmap: fmap,
|
||||
fh := &functionHandler{
|
||||
logger: logger,
|
||||
fmap: fmap,
|
||||
function: fn,
|
||||
tsRoundTripperParams: &tsRoundTripperParams{
|
||||
timeout: 50 * time.Millisecond,
|
||||
|
||||
@@ -17,9 +17,10 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/cache"
|
||||
"github.com/fission/fission/crd"
|
||||
@@ -27,14 +28,16 @@ import (
|
||||
|
||||
type (
|
||||
functionRecorderMap struct {
|
||||
cache *cache.Cache // map[string]*crd.Recorder
|
||||
logger *zap.Logger
|
||||
cache *cache.Cache // map[string]*crd.Recorder
|
||||
}
|
||||
)
|
||||
|
||||
// Why do we need an expiry?
|
||||
func makeFunctionRecorderMap(expiry time.Duration) *functionRecorderMap {
|
||||
func makeFunctionRecorderMap(logger *zap.Logger, expiry time.Duration) *functionRecorderMap {
|
||||
return &functionRecorderMap{
|
||||
cache: cache.MakeCache(expiry, 0),
|
||||
logger: logger.Named("function_recorder_map"),
|
||||
cache: cache.MakeCache(expiry, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +56,7 @@ func (frmap *functionRecorderMap) assign(function string, recorder *crd.Recorder
|
||||
if e, ok := err.(fission.Error); ok && e.Code == fission.ErrorNameExists {
|
||||
return
|
||||
}
|
||||
log.Printf("error caching recorder for function name with a different value: %v", err)
|
||||
frmap.logger.Error("error caching recorder for function name with a different value", zap.Error(err))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/cache"
|
||||
@@ -28,7 +28,8 @@ import (
|
||||
|
||||
type (
|
||||
functionServiceMap struct {
|
||||
cache *cache.Cache // map[metadataKey]*url.URL
|
||||
logger *zap.Logger
|
||||
cache *cache.Cache // map[metadataKey]*url.URL
|
||||
}
|
||||
|
||||
// metav1.ObjectMeta is not hashable, so we make a hashable copy
|
||||
@@ -40,9 +41,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func makeFunctionServiceMap(expiry time.Duration) *functionServiceMap {
|
||||
func makeFunctionServiceMap(logger *zap.Logger, expiry time.Duration) *functionServiceMap {
|
||||
return &functionServiceMap{
|
||||
cache: cache.MakeCache(expiry, 0),
|
||||
logger: logger.Named("function_service_map"),
|
||||
cache: cache.MakeCache(expiry, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ func (fmap *functionServiceMap) assign(f *metav1.ObjectMeta, serviceUrl *url.URL
|
||||
if *serviceUrl == *(old.(*url.URL)) {
|
||||
return
|
||||
}
|
||||
log.Printf("error caching service url for function with a different value: %v", err)
|
||||
fmap.logger.Error("error caching service url for function with a different value", zap.Error(err))
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,16 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestFunctionServiceMap(t *testing.T) {
|
||||
m := makeFunctionServiceMap(0)
|
||||
logger, err := zap.NewDevelopment()
|
||||
panicIf(err)
|
||||
|
||||
m := makeFunctionServiceMap(logger, 0)
|
||||
fn := &metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault}
|
||||
u, err := url.Parse("/foo012")
|
||||
if err != nil {
|
||||
|
||||
+19
-12
@@ -18,11 +18,11 @@ package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@@ -39,6 +39,7 @@ type HTTPTriggerSet struct {
|
||||
*functionServiceMap
|
||||
*mutableRouter
|
||||
|
||||
logger *zap.Logger
|
||||
fissionClient *crd.FissionClient
|
||||
kubeClient *kubernetes.Clientset
|
||||
executor *executorClient.Client
|
||||
@@ -57,10 +58,11 @@ type HTTPTriggerSet struct {
|
||||
svcAddrUpdateThrottler *throttler.Throttler
|
||||
}
|
||||
|
||||
func makeHTTPTriggerSet(fmap *functionServiceMap, frmap *functionRecorderMap, trmap *triggerRecorderMap, fissionClient *crd.FissionClient,
|
||||
func makeHTTPTriggerSet(logger *zap.Logger, fmap *functionServiceMap, frmap *functionRecorderMap, trmap *triggerRecorderMap, fissionClient *crd.FissionClient,
|
||||
kubeClient *kubernetes.Clientset, executor *executorClient.Client, crdClient *rest.RESTClient, params *tsRoundTripperParams, isDebugEnv bool, actionThrottler *throttler.Throttler) (*HTTPTriggerSet, k8sCache.Store, k8sCache.Store) {
|
||||
|
||||
httpTriggerSet := &HTTPTriggerSet{
|
||||
logger: logger.Named("http_trigger_set"),
|
||||
functionServiceMap: fmap,
|
||||
triggers: []crd.HTTPTrigger{},
|
||||
fissionClient: fissionClient,
|
||||
@@ -83,7 +85,7 @@ func makeHTTPTriggerSet(fmap *functionServiceMap, frmap *functionRecorderMap, tr
|
||||
httpTriggerSet.funcStore = fnStore
|
||||
httpTriggerSet.funcController = fnController
|
||||
}
|
||||
recorderSet = MakeRecorderSet(httpTriggerSet, crdClient, rStore, frmap, trmap)
|
||||
recorderSet = MakeRecorderSet(logger, httpTriggerSet, crdClient, rStore, frmap, trmap)
|
||||
httpTriggerSet.recorderSet = recorderSet
|
||||
return httpTriggerSet, tStore, fnStore
|
||||
}
|
||||
@@ -95,7 +97,7 @@ func (ts *HTTPTriggerSet) subscribeRouter(ctx context.Context, mr *mutableRouter
|
||||
|
||||
if ts.fissionClient == nil {
|
||||
// Used in tests only.
|
||||
log.Printf("Skipping continuous trigger updates")
|
||||
ts.logger.Info("skipping continuous trigger updates")
|
||||
return
|
||||
}
|
||||
go ts.updateRouter()
|
||||
@@ -104,7 +106,7 @@ func (ts *HTTPTriggerSet) subscribeRouter(ctx context.Context, mr *mutableRouter
|
||||
if ts.recorderSet.recController != nil {
|
||||
go ts.runWatcher(ctx, ts.recorderSet.recController)
|
||||
} else {
|
||||
log.Fatal("Failed to run recorder Controller")
|
||||
ts.logger.Fatal("failed to run recorder controller")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,10 +145,11 @@ func (ts *HTTPTriggerSet) getRouter() *mux.Router {
|
||||
|
||||
if rr.resolveResultType != resolveResultSingleFunction && rr.resolveResultType != resolveResultMultipleFunctions {
|
||||
// not implemented yet
|
||||
log.Panicf("resolve result type not implemented (%v)", rr.resolveResultType)
|
||||
ts.logger.Panic("resolve result type not implemented", zap.Any("type", rr.resolveResultType))
|
||||
}
|
||||
|
||||
fh := &functionHandler{
|
||||
logger: ts.logger.Named(trigger.Metadata.Name),
|
||||
fmap: ts.functionServiceMap,
|
||||
frmap: ts.recorderSet.functionRecorderMap,
|
||||
trmap: ts.recorderSet.triggerRecorderMap,
|
||||
@@ -205,6 +208,7 @@ func (ts *HTTPTriggerSet) getRouter() *mux.Router {
|
||||
}
|
||||
|
||||
fh := &functionHandler{
|
||||
logger: ts.logger.Named(m.Name),
|
||||
fmap: ts.functionServiceMap,
|
||||
frmap: ts.recorderSet.functionRecorderMap,
|
||||
trmap: ts.recorderSet.triggerRecorderMap,
|
||||
@@ -235,7 +239,7 @@ func (ts *HTTPTriggerSet) initTriggerController() (k8sCache.Store, k8sCache.Cont
|
||||
k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
trigger := obj.(*crd.HTTPTrigger)
|
||||
go createIngress(trigger, ts.kubeClient)
|
||||
go createIngress(ts.logger, trigger, ts.kubeClient)
|
||||
ts.syncTriggers()
|
||||
// Check if this trigger's function needs to be recorded
|
||||
fnRef := trigger.Spec.FunctionReference.Name
|
||||
@@ -244,14 +248,17 @@ func (ts *HTTPTriggerSet) initTriggerController() (k8sCache.Store, k8sCache.Cont
|
||||
if len(recorder.Spec.Triggers) == 0 {
|
||||
ts.recorderSet.triggerRecorderMap.assign(trigger.Metadata.Name, recorder)
|
||||
}
|
||||
} else if err != nil {
|
||||
ts.logger.Error("unable to lookup function in functionRecorderMap", zap.Error(err))
|
||||
} else {
|
||||
log.Print("Unable to lookup function in functionRecorderMap")
|
||||
ts.logger.Error("unable to lookup function in functionRecorderMap")
|
||||
|
||||
}
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
ts.syncTriggers()
|
||||
trigger := obj.(*crd.HTTPTrigger)
|
||||
go deleteIngress(trigger, ts.kubeClient)
|
||||
go deleteIngress(ts.logger, trigger, ts.kubeClient)
|
||||
go ts.recorderSet.DeleteTriggerFromRecorderMap(trigger)
|
||||
},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
@@ -262,7 +269,7 @@ func (ts *HTTPTriggerSet) initTriggerController() (k8sCache.Store, k8sCache.Cont
|
||||
return
|
||||
}
|
||||
|
||||
go updateIngress(oldTrigger, newTrigger, ts.kubeClient)
|
||||
go updateIngress(ts.logger, oldTrigger, newTrigger, ts.kubeClient)
|
||||
ts.syncTriggers()
|
||||
},
|
||||
})
|
||||
@@ -296,10 +303,10 @@ func (ts *HTTPTriggerSet) initFunctionController() (k8sCache.Store, k8sCache.Con
|
||||
rr.functionMetadataMap[fn.Metadata.Name] != nil &&
|
||||
rr.functionMetadataMap[fn.Metadata.Name].ResourceVersion != fn.Metadata.ResourceVersion {
|
||||
// invalidate resolver cache
|
||||
log.Printf("Invalidating resolver cache")
|
||||
ts.logger.Info("invalidating resolver cache")
|
||||
err := ts.resolver.delete(key.namespace, key.triggerName, key.triggerResourceVersion)
|
||||
if err != nil {
|
||||
log.Printf("Error deleting functionReferenceResolver cache: %v", err)
|
||||
ts.logger.Error("error deleting functionReferenceResolver cache", zap.Error(err))
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
+20
-15
@@ -17,9 +17,9 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -38,16 +38,16 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func createIngress(trigger *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
func createIngress(logger *zap.Logger, trigger *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
|
||||
if !trigger.Spec.CreateIngress {
|
||||
log.Printf("Skipping creation of ingress for trigger: %v", trigger.Metadata.Name)
|
||||
logger.Info("skipping creation of ingress for trigger", zap.String("trigger", trigger.Metadata.Name))
|
||||
return
|
||||
}
|
||||
|
||||
_, err := kubeClient.ExtensionsV1beta1().Ingresses(podNamespace).Get(trigger.Metadata.Name, v1.GetOptions{})
|
||||
if err == nil {
|
||||
log.Printf("Ingress for trigger exists already %v", trigger.Metadata.Name)
|
||||
logger.Info("ingress for trigger exists already", zap.String("trigger", trigger.Metadata.Name))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,10 +87,10 @@ func createIngress(trigger *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
|
||||
_, err = kubeClient.ExtensionsV1beta1().Ingresses(podNamespace).Create(ing)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create ingress: %v", err)
|
||||
logger.Error("failed to create ingress", zap.Error(err))
|
||||
return
|
||||
}
|
||||
log.Printf("Created ingress successfully for trigger %v", trigger.Metadata.Name)
|
||||
logger.Info("created ingress successfully for trigger", zap.String("trigger", trigger.Metadata.Name))
|
||||
}
|
||||
|
||||
func getDeployLabels(trigger *crd.HTTPTrigger) map[string]string {
|
||||
@@ -101,41 +101,46 @@ func getDeployLabels(trigger *crd.HTTPTrigger) map[string]string {
|
||||
}
|
||||
}
|
||||
|
||||
func deleteIngress(trigger *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
func deleteIngress(logger *zap.Logger, trigger *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
if !trigger.Spec.CreateIngress {
|
||||
return
|
||||
}
|
||||
|
||||
ingress, err := kubeClient.ExtensionsV1beta1().Ingresses(podNamespace).Get(trigger.Metadata.Name, v1.GetOptions{})
|
||||
if err != nil {
|
||||
log.Printf("Failed to get ingress when deleting trigger: %v, %v", err, trigger)
|
||||
logger.Error("failed to get ingress when deleting trigger", zap.Error(err), zap.String("trigger", trigger.Metadata.Name))
|
||||
}
|
||||
|
||||
err = kubeClient.ExtensionsV1beta1().Ingresses(podNamespace).Delete(ingress.Name, &v1.DeleteOptions{})
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to delete ingress %v error: %v", ingress, err)
|
||||
logger.Error("failed to delete ingress for trigger",
|
||||
zap.Error(err),
|
||||
zap.Any("ingress", ingress),
|
||||
zap.String("trigger", trigger.Metadata.Name))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func updateIngress(oldT *crd.HTTPTrigger, newT *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
func updateIngress(logger *zap.Logger, oldT *crd.HTTPTrigger, newT *crd.HTTPTrigger, kubeClient *kubernetes.Clientset) {
|
||||
|
||||
if oldT.Spec.CreateIngress == false && newT.Spec.CreateIngress == true {
|
||||
createIngress(newT, kubeClient)
|
||||
createIngress(logger, newT, kubeClient)
|
||||
return
|
||||
}
|
||||
|
||||
if newT.Spec.CreateIngress == false && oldT.Spec.CreateIngress == true {
|
||||
deleteIngress(oldT, kubeClient)
|
||||
deleteIngress(logger, oldT, kubeClient)
|
||||
return
|
||||
}
|
||||
|
||||
if newT.Spec.Host != oldT.Spec.Host || newT.Spec.RelativeURL != oldT.Spec.RelativeURL {
|
||||
log.Printf("Updating ingress for trigger %v", oldT.Metadata.Name)
|
||||
logger.Info("updating ingress for trigger", zap.String("trigger", oldT.Metadata.Name))
|
||||
ingress, err := kubeClient.ExtensionsV1beta1().Ingresses(podNamespace).Get(oldT.Metadata.Name, v1.GetOptions{})
|
||||
if err != nil {
|
||||
log.Printf("Failed to get ingress when updating trigger: %v", err)
|
||||
logger.Error("failed to get ingress when updating trigger",
|
||||
zap.Error(err),
|
||||
zap.String("trigger", oldT.Metadata.Name))
|
||||
}
|
||||
|
||||
if newT.Spec.Host != oldT.Spec.Host {
|
||||
@@ -148,7 +153,7 @@ func updateIngress(oldT *crd.HTTPTrigger, newT *crd.HTTPTrigger, kubeClient *kub
|
||||
|
||||
_, err = kubeClient.ExtensionsV1beta1().Ingresses(podNamespace).Update(ingress)
|
||||
if err != nil {
|
||||
log.Printf("Failed to update ingress for trigger: %v", err)
|
||||
logger.Error("failed to update ingress for trigger", zap.String("trigger", oldT.Metadata.Name))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
//
|
||||
@@ -30,11 +30,14 @@ import (
|
||||
//
|
||||
|
||||
type mutableRouter struct {
|
||||
logger *zap.Logger
|
||||
router atomic.Value // mux.Router
|
||||
}
|
||||
|
||||
func NewMutableRouter(handler *mux.Router) *mutableRouter {
|
||||
mr := mutableRouter{}
|
||||
func NewMutableRouter(logger *zap.Logger, handler *mux.Router) *mutableRouter {
|
||||
mr := mutableRouter{
|
||||
logger: logger.Named("mutable_router"),
|
||||
}
|
||||
mr.router.Store(handler)
|
||||
return &mr
|
||||
}
|
||||
@@ -44,7 +47,7 @@ func (mr *mutableRouter) ServeHTTP(responseWriter http.ResponseWriter, request *
|
||||
routerValue := mr.router.Load()
|
||||
router, ok := routerValue.(*mux.Router)
|
||||
if !ok {
|
||||
log.Panic("Invalid router type")
|
||||
mr.logger.Panic("invalid router type")
|
||||
}
|
||||
router.ServeHTTP(responseWriter, request)
|
||||
}
|
||||
|
||||
@@ -17,11 +17,13 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"log"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func OldHandler(responseWriter http.ResponseWriter, request *http.Request) {
|
||||
@@ -62,7 +64,10 @@ func TestMutableMux(t *testing.T) {
|
||||
log.Print("Create mutable router")
|
||||
muxRouter := mux.NewRouter()
|
||||
muxRouter.HandleFunc("/", OldHandler)
|
||||
mr := NewMutableRouter(muxRouter)
|
||||
logger, err := zap.NewDevelopment()
|
||||
panicIf(err)
|
||||
|
||||
mr := NewMutableRouter(logger, muxRouter)
|
||||
|
||||
// start http server
|
||||
log.Print("Start http server")
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/fission/fission/crd"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.uber.org/zap"
|
||||
"k8s.io/client-go/rest"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type RecorderSet struct {
|
||||
logger *zap.Logger
|
||||
|
||||
httpTriggerSet *HTTPTriggerSet
|
||||
|
||||
crdClient *rest.RESTClient
|
||||
@@ -19,8 +22,9 @@ type RecorderSet struct {
|
||||
triggerRecorderMap *triggerRecorderMap
|
||||
}
|
||||
|
||||
func MakeRecorderSet(httpTriggerSet *HTTPTriggerSet, crdClient *rest.RESTClient, rStore k8sCache.Store, frmap *functionRecorderMap, trmap *triggerRecorderMap) *RecorderSet {
|
||||
func MakeRecorderSet(logger *zap.Logger, httpTriggerSet *HTTPTriggerSet, crdClient *rest.RESTClient, rStore k8sCache.Store, frmap *functionRecorderMap, trmap *triggerRecorderMap) *RecorderSet {
|
||||
recorderSet := &RecorderSet{
|
||||
logger: logger.Named("recorder_set"),
|
||||
httpTriggerSet: httpTriggerSet,
|
||||
crdClient: crdClient,
|
||||
recStore: rStore,
|
||||
@@ -63,12 +67,17 @@ func (rs *RecorderSet) disableRecorder(r *crd.Recorder) {
|
||||
function := r.Spec.Function
|
||||
triggers := r.Spec.Triggers
|
||||
|
||||
log.Info("Disabling recorder ", r.Metadata.Name)
|
||||
rs.logger.Info("disabling recorder",
|
||||
zap.String("recorder", r.Metadata.Name),
|
||||
zap.String("function", function))
|
||||
|
||||
// Account for function
|
||||
err := rs.functionRecorderMap.remove(function)
|
||||
if err != nil {
|
||||
log.Error("Error disabling recorder (failed to remove function from functionRecorderMap): ", err)
|
||||
rs.logger.Error("error disabling recorder (failed to remove function from functionRecorderMap)",
|
||||
zap.Error(err),
|
||||
zap.String("recorder", r.Metadata.Name),
|
||||
zap.String("function", function))
|
||||
}
|
||||
|
||||
// Account for explicitly added triggers
|
||||
@@ -76,7 +85,11 @@ func (rs *RecorderSet) disableRecorder(r *crd.Recorder) {
|
||||
for _, trigger := range triggers {
|
||||
err := rs.triggerRecorderMap.remove(trigger)
|
||||
if err != nil {
|
||||
log.Error("Error disabling recorder (failed to remove triggers from triggerRecorderMap): ", err)
|
||||
rs.logger.Error("error disabling recorder (failed to remove triggers from triggerRecorderMap)",
|
||||
zap.Error(err),
|
||||
zap.String("recorder", r.Metadata.Name),
|
||||
zap.String("function", function),
|
||||
zap.String("trigger", trigger))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -86,7 +99,11 @@ func (rs *RecorderSet) disableRecorder(r *crd.Recorder) {
|
||||
if trigger.Spec.FunctionReference.Name == function {
|
||||
err := rs.triggerRecorderMap.remove(trigger.Metadata.Name)
|
||||
if err != nil {
|
||||
log.Error("Failed to remove trigger from triggerRecorderMap: ", err)
|
||||
rs.logger.Error("failed to remove trigger from triggerRecorderMap",
|
||||
zap.Error(err),
|
||||
zap.String("recorder", r.Metadata.Name),
|
||||
zap.String("function", function),
|
||||
zap.String("trigger", trigger.Metadata.Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,13 +123,13 @@ func (rs *RecorderSet) updateRecorder(old *crd.Recorder, newer *crd.Recorder) {
|
||||
func (rs *RecorderSet) DeleteTriggerFromRecorderMap(trigger *crd.HTTPTrigger) {
|
||||
err := rs.triggerRecorderMap.remove(trigger.Metadata.Name)
|
||||
if err != nil {
|
||||
log.Error("Failed to remove trigger from triggerRecorderMap: ", err)
|
||||
rs.logger.Error("failed to remove trigger from triggerRecorderMap", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *RecorderSet) DeleteFunctionFromRecorderMap(function *crd.Function) {
|
||||
err := rs.functionRecorderMap.remove(function.Metadata.Name)
|
||||
if err != nil {
|
||||
log.Error("Failed to remove function from functionRecorderMap: ", err)
|
||||
rs.logger.Error("failed to remove function from functionRecorderMap", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
+57
-32
@@ -42,7 +42,6 @@ package router
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -52,6 +51,7 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"go.opencensus.io/trace"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
@@ -63,16 +63,16 @@ import (
|
||||
|
||||
// request url ---[trigger]---> Function(name, deployment) ----[deployment]----> Function(name, uid) ----[pool mgr]---> k8s service url
|
||||
|
||||
func router(ctx context.Context, httpTriggerSet *HTTPTriggerSet, resolver *functionReferenceResolver) *mutableRouter {
|
||||
func router(ctx context.Context, logger *zap.Logger, httpTriggerSet *HTTPTriggerSet, resolver *functionReferenceResolver) *mutableRouter {
|
||||
muxRouter := mux.NewRouter()
|
||||
mr := NewMutableRouter(muxRouter)
|
||||
muxRouter.Use(fission.LoggingMiddleware)
|
||||
mr := NewMutableRouter(logger, muxRouter)
|
||||
muxRouter.Use(fission.LoggingMiddleware(logger))
|
||||
httpTriggerSet.subscribeRouter(ctx, mr, resolver)
|
||||
return mr
|
||||
}
|
||||
|
||||
func serve(ctx context.Context, port int, httpTriggerSet *HTTPTriggerSet, resolver *functionReferenceResolver) {
|
||||
mr := router(ctx, httpTriggerSet, resolver)
|
||||
func serve(ctx context.Context, logger *zap.Logger, port int, httpTriggerSet *HTTPTriggerSet, resolver *functionReferenceResolver) {
|
||||
mr := router(ctx, logger, httpTriggerSet, resolver)
|
||||
url := fmt.Sprintf(":%v", port)
|
||||
http.ListenAndServe(url, &ochttp.Handler{
|
||||
Handler: mr,
|
||||
@@ -82,77 +82,102 @@ func serve(ctx context.Context, port int, httpTriggerSet *HTTPTriggerSet, resolv
|
||||
})
|
||||
}
|
||||
|
||||
func serveMetric() {
|
||||
func serveMetric(logger *zap.Logger) {
|
||||
// Expose the registered metrics via HTTP.
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
log.Fatal(http.ListenAndServe(metricAddr, nil))
|
||||
err := http.ListenAndServe(metricAddr, nil)
|
||||
|
||||
logger.Fatal("done listening on metrics endpoint", zap.Error(err))
|
||||
}
|
||||
|
||||
func Start(port int, executorUrl string) {
|
||||
func Start(logger *zap.Logger, port int, executorUrl string) {
|
||||
// setup a signal handler for SIGTERM
|
||||
fission.SetupStackTraceHandler()
|
||||
|
||||
fmap := makeFunctionServiceMap(time.Minute)
|
||||
fmap := makeFunctionServiceMap(logger, time.Minute)
|
||||
|
||||
frmap := makeFunctionRecorderMap(time.Minute)
|
||||
frmap := makeFunctionRecorderMap(logger, time.Minute)
|
||||
|
||||
trmap := makeTriggerRecorderMap(time.Minute)
|
||||
trmap := makeTriggerRecorderMap(logger, time.Minute)
|
||||
|
||||
fissionClient, kubeClient, _, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
log.Fatalf("Error connecting to kubernetes API: %v", err)
|
||||
logger.Fatal("error connecting to kubernetes API", zap.Error(err))
|
||||
}
|
||||
|
||||
err = fissionClient.WaitForCRDs()
|
||||
if err != nil {
|
||||
log.Fatalf("Error waiting for CRDs: %v", err)
|
||||
logger.Fatal("error waiting for CRDs", zap.Error(err))
|
||||
}
|
||||
|
||||
restClient := fissionClient.GetCrdClient()
|
||||
|
||||
executor := executorClient.MakeClient(executorUrl)
|
||||
executor := executorClient.MakeClient(logger, executorUrl)
|
||||
|
||||
timeout, err := time.ParseDuration(os.Getenv("ROUTER_ROUND_TRIP_TIMEOUT"))
|
||||
timeoutStr := os.Getenv("ROUTER_ROUND_TRIP_TIMEOUT")
|
||||
timeout, err := time.ParseDuration(timeoutStr)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse timeout: %v", err)
|
||||
logger.Fatal("failed to parse timeout duration from 'ROUTER_ROUND_TRIP_TIMEOUT'",
|
||||
zap.Error(err),
|
||||
zap.String("value", timeoutStr))
|
||||
}
|
||||
|
||||
timeoutExponent, err := strconv.Atoi(os.Getenv("ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT"))
|
||||
timeoutExponentStr := os.Getenv("ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT")
|
||||
timeoutExponent, err := strconv.Atoi(timeoutExponentStr)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse timeout exponent: %v", err)
|
||||
logger.Fatal("failed to parse timeout exponent from 'ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT'",
|
||||
zap.Error(err),
|
||||
zap.String("value", timeoutExponentStr))
|
||||
}
|
||||
|
||||
keepAlive, err := time.ParseDuration(os.Getenv("ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME"))
|
||||
keepAliveStr := os.Getenv("ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME")
|
||||
keepAlive, err := time.ParseDuration(keepAliveStr)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse keep alive time: %v", err)
|
||||
logger.Fatal("failed to parse keep alive duration from 'ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME'",
|
||||
zap.Error(err),
|
||||
zap.String("value", keepAliveStr))
|
||||
}
|
||||
|
||||
maxRetries, err := strconv.Atoi(os.Getenv("ROUTER_ROUND_TRIP_MAX_RETRIES"))
|
||||
maxRetriesStr := os.Getenv("ROUTER_ROUND_TRIP_MAX_RETRIES")
|
||||
maxRetries, err := strconv.Atoi(maxRetriesStr)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse max retry times: %v", err)
|
||||
logger.Fatal("failed to parse max retries from 'ROUTER_ROUND_TRIP_MAX_RETRIES'",
|
||||
zap.Error(err),
|
||||
zap.String("value", maxRetriesStr))
|
||||
}
|
||||
|
||||
isDebugEnv, err := strconv.ParseBool(os.Getenv("DEBUG_ENV"))
|
||||
isDebugEnvStr := os.Getenv("DEBUG_ENV")
|
||||
isDebugEnv, err := strconv.ParseBool(isDebugEnvStr)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse DEBUG_ENV: %v", err)
|
||||
logger.Fatal("failed to parse debug env from 'DEBUG_ENV'",
|
||||
zap.Error(err),
|
||||
zap.String("value", isDebugEnvStr))
|
||||
}
|
||||
|
||||
// svcAddrRetryCount is the max times for RetryingRoundTripper to retry with a specific service address
|
||||
svcAddrRetryCount, err := strconv.Atoi(os.Getenv("ROUTER_ROUND_TRIP_SVC_ADDRESS_MAX_RETRIES"))
|
||||
svcAddrRetryCountStr := os.Getenv("ROUTER_ROUND_TRIP_SVC_ADDRESS_MAX_RETRIES")
|
||||
svcAddrRetryCount, err := strconv.Atoi(svcAddrRetryCountStr)
|
||||
if err != nil {
|
||||
svcAddrRetryCount = 5
|
||||
log.Printf("Failed to parse svc address retry conunt, set it to default value(5): %v", err)
|
||||
logger.Info("failed to parse service address retry count from 'ROUTER_ROUND_TRIP_SVC_ADDRESS_MAX_RETRIES' - set to the default value",
|
||||
zap.Error(err),
|
||||
zap.String("value", svcAddrRetryCountStr),
|
||||
zap.Int("default", svcAddrRetryCount))
|
||||
}
|
||||
|
||||
// svcAddrUpdateTimeout is the timeout setting for a goroutine to wait for the update of a service entry.
|
||||
// If the update process cannot be done within the timeout window, consider it failed.
|
||||
svcAddrUpdateTimeoutStr := os.Getenv("ROUTER_ROUND_TRIP_SVC_ADDRESS_UPDATE_TIMEOUT")
|
||||
svcAddrUpdateTimeout, err := time.ParseDuration(os.Getenv("ROUTER_ROUND_TRIP_SVC_ADDRESS_UPDATE_TIMEOUT"))
|
||||
if err != nil {
|
||||
svcAddrUpdateTimeout = 30 * time.Second
|
||||
log.Printf("Failed to parse svc address update timeout, set it to default value(30): %v", err)
|
||||
logger.Info("failed to parse service address update timeout duration from 'ROUTER_ROUND_TRIP_SVC_ADDRESS_UPDATE_TIMEOUT' - set to the default value",
|
||||
zap.Error(err),
|
||||
zap.String("value", svcAddrUpdateTimeoutStr),
|
||||
zap.Duration("default", svcAddrUpdateTimeout))
|
||||
}
|
||||
|
||||
triggers, _, fnStore := makeHTTPTriggerSet(fmap, frmap, trmap, fissionClient, kubeClient, executor, restClient, &tsRoundTripperParams{
|
||||
triggers, _, fnStore := makeHTTPTriggerSet(logger.Named("triggerset"), fmap, frmap, trmap, fissionClient, kubeClient, executor, restClient, &tsRoundTripperParams{
|
||||
timeout: timeout,
|
||||
timeoutExponent: timeoutExponent,
|
||||
keepAlive: keepAlive,
|
||||
@@ -162,10 +187,10 @@ func Start(port int, executorUrl string) {
|
||||
|
||||
resolver := makeFunctionReferenceResolver(fnStore)
|
||||
|
||||
go serveMetric()
|
||||
go serveMetric(logger)
|
||||
|
||||
log.Printf("Starting router at port %v\n", port)
|
||||
logger.Info("starting router", zap.Int("port", port))
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
serve(ctx, port, triggers, resolver)
|
||||
serve(ctx, logger, port, triggers, resolver)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
@@ -43,16 +44,19 @@ func TestRouter(t *testing.T) {
|
||||
testResponseString := "hi"
|
||||
testServiceUrl := createBackendService(testResponseString)
|
||||
|
||||
logger, err := zap.NewDevelopment()
|
||||
panicIf(err)
|
||||
|
||||
// set up the cache with this fake service
|
||||
fmap := makeFunctionServiceMap(0)
|
||||
fmap := makeFunctionServiceMap(logger, 0)
|
||||
fmap.assign(fn, testServiceUrl)
|
||||
|
||||
frmap := makeFunctionRecorderMap(time.Minute)
|
||||
frmap := makeFunctionRecorderMap(logger, time.Minute)
|
||||
|
||||
trmap := makeTriggerRecorderMap(time.Minute)
|
||||
trmap := makeTriggerRecorderMap(logger, time.Minute)
|
||||
|
||||
// HTTP trigger set with a trigger for this function
|
||||
triggers, _, _ := makeHTTPTriggerSet(fmap, frmap, trmap, nil, nil, nil, nil,
|
||||
triggers, _, _ := makeHTTPTriggerSet(logger, fmap, frmap, trmap, nil, nil, nil, nil,
|
||||
&tsRoundTripperParams{
|
||||
timeout: 50 * time.Millisecond,
|
||||
timeoutExponent: 2,
|
||||
@@ -95,7 +99,7 @@ func TestRouter(t *testing.T) {
|
||||
port := 4242
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go serve(ctx, port, triggers, frr)
|
||||
go serve(ctx, logger, port, triggers, frr)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// hit the router
|
||||
|
||||
@@ -17,9 +17,10 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/cache"
|
||||
"github.com/fission/fission/crd"
|
||||
@@ -27,13 +28,15 @@ import (
|
||||
|
||||
type (
|
||||
triggerRecorderMap struct {
|
||||
cache *cache.Cache // map[string]*crd.Recorder
|
||||
logger *zap.Logger
|
||||
cache *cache.Cache // map[string]*crd.Recorder
|
||||
}
|
||||
)
|
||||
|
||||
func makeTriggerRecorderMap(expiry time.Duration) *triggerRecorderMap {
|
||||
func makeTriggerRecorderMap(logger *zap.Logger, expiry time.Duration) *triggerRecorderMap {
|
||||
return &triggerRecorderMap{
|
||||
cache: cache.MakeCache(expiry, 0),
|
||||
logger: logger.Named("trigger_recorder_map"),
|
||||
cache: cache.MakeCache(expiry, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +55,7 @@ func (trmap *triggerRecorderMap) assign(trigger string, recorder *crd.Recorder)
|
||||
if e, ok := err.(fission.Error); ok && e.Code == fission.ErrorNameExists {
|
||||
return
|
||||
}
|
||||
log.Printf("error caching recorder for function name with a different value: %v", err)
|
||||
trmap.logger.Error("error caching recorder for function name with a different value", zap.Error(err))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,3 +28,9 @@ func testRequest(targetUrl string, expectedResponse string) {
|
||||
log.Panic("Unexpected response")
|
||||
}
|
||||
}
|
||||
|
||||
func panicIf(err error) {
|
||||
if err != nil {
|
||||
log.Panicf("Error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user