diff --git a/pkg/apis/core/v1/types.go b/pkg/apis/core/v1/types.go index c5ae1dbfb..38a4b265f 100644 --- a/pkg/apis/core/v1/types.go +++ b/pkg/apis/core/v1/types.go @@ -357,6 +357,10 @@ type ( // RequestsPerPod indicates the maximum number of concurrent requests that can be served by a specialized pod // This is optional. If not specified default value will be taken as 1 RequestsPerPod int `json:"requestsPerPod,omitempty"` + + // OnceOnly specifies if specialized pod will serve exactly one request in its lifetime and would be garbage collected after serving that one request + // This is optional. If not specified default value will be taken as false + OnceOnly bool `json:"onceOnly,omitempty"` } // InvokeStrategy is a set of controls over how the function executes. diff --git a/pkg/crd/crdvalidations.go b/pkg/crd/crdvalidations.go index c1dd072e9..a080b898e 100644 --- a/pkg/crd/crdvalidations.go +++ b/pkg/crd/crdvalidations.go @@ -53,6 +53,10 @@ var ( Type: "integer", Description: "RequestsPerPod indicates the maximum number of concurrent requests that can be served by a specialized pod.\n This is optional. If not specified default value will be taken as 1", }, + "onceOnly": { + Type: "boolean", + Description: "OnceOnly specifies if specialized pod will serve exactly one request in its lifetime and would be garbage collected after serving that one request.\nThis is optional. If not specified default value will be taken as false", + }, }, }, } diff --git a/pkg/executor/api.go b/pkg/executor/api.go index 979ea3166..72c92b80a 100644 --- a/pkg/executor/api.go +++ b/pkg/executor/api.go @@ -56,7 +56,7 @@ func (executor *Executor) getServiceForFunctionAPI(w http.ResponseWriter, r *htt executor.logger.Debug("checking for cached function service", zap.String("function_name", fn.ObjectMeta.Name), zap.String("function_namespace", fn.ObjectMeta.Namespace)) - if t == fv1.ExecutorTypePoolmgr { + if t == fv1.ExecutorTypePoolmgr && !fn.Spec.OnceOnly { concurrency := fn.Spec.Concurrency if concurrency == 0 { concurrency = 500 @@ -90,7 +90,7 @@ func (executor *Executor) getServiceForFunctionAPI(w http.ResponseWriter, r *htt http.Error(w, errMsg, http.StatusTooManyRequests) return } - } else { + } else if t == fv1.ExecutorTypeNewdeploy { fsvc, err := et.GetFuncSvcFromCache(fn) if err == nil { if et.IsValid(fsvc) { diff --git a/pkg/fission-cli/cmd/function/command.go b/pkg/fission-cli/cmd/function/command.go index 2e1d3a5f6..1f665d87a 100644 --- a/pkg/fission-cli/cmd/function/command.go +++ b/pkg/fission-cli/cmd/function/command.go @@ -36,6 +36,7 @@ func Commands() *cobra.Command { flag.FnExecutorType, flag.FnCfgMap, flag.FnSecret, flag.FnSpecializationTimeout, flag.FnExecutionTimeout, flag.FnIdleTimeout, flag.FnConcurrency, flag.FnRequestsPerPod, + flag.FnOnceOnly, // TODO retired pkg & trigger related flags from function cmd flag.PkgCode, flag.PkgSrcArchive, flag.PkgDeployArchive, @@ -87,6 +88,7 @@ func Commands() *cobra.Command { flag.FnExecutorType, flag.FnSecret, flag.FnCfgMap, flag.FnSpecializationTimeout, flag.FnExecutionTimeout, flag.FnIdleTimeout, flag.FnConcurrency, flag.FnRequestsPerPod, + flag.FnOnceOnly, flag.PkgCode, flag.PkgSrcArchive, flag.PkgDeployArchive, flag.PkgSrcChecksum, flag.PkgDeployChecksum, flag.PkgInsecure, diff --git a/pkg/fission-cli/cmd/function/create.go b/pkg/fission-cli/cmd/function/create.go index 58ffa0db6..79bc25bee 100644 --- a/pkg/fission-cli/cmd/function/create.go +++ b/pkg/fission-cli/cmd/function/create.go @@ -104,6 +104,8 @@ func (opts *CreateSubCommand) complete(input cli.Input) error { requestsPerPod := input.Int(flagkey.FnRequestsPerPod) + fnOnceOnly := input.Bool(flagkey.FnOnceOnly) + pkgName := input.String(flagkey.FnPackageName) secretNames := input.StringSlice(flagkey.FnSecret) @@ -304,6 +306,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error { IdleTimeout: &fnIdleTimeout, Concurrency: fnConcurrency, RequestsPerPod: requestsPerPod, + OnceOnly: fnOnceOnly, }, } diff --git a/pkg/fission-cli/cmd/function/update.go b/pkg/fission-cli/cmd/function/update.go index 37714a239..c8ef7f497 100644 --- a/pkg/fission-cli/cmd/function/update.go +++ b/pkg/fission-cli/cmd/function/update.go @@ -163,6 +163,9 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error { function.Spec.RequestsPerPod = input.Int(flagkey.FnRequestsPerPod) } + if input.IsSet(flagkey.FnOnceOnly) { + function.Spec.OnceOnly = input.Bool(flagkey.FnOnceOnly) + } if len(pkgName) == 0 { pkgName = function.Spec.Package.PackageRef.Name } diff --git a/pkg/fission-cli/flag/flag.go b/pkg/fission-cli/flag/flag.go index 653514915..e809417df 100644 --- a/pkg/fission-cli/flag/flag.go +++ b/pkg/fission-cli/flag/flag.go @@ -112,6 +112,7 @@ var ( FnIdleTimeout = Flag{Type: Int, Name: flagkey.FnIdleTimeout, Usage: "The length of time (in seconds) that a function is idle before pod(s) are eligible for recycling", DefaultValue: 120} FnConcurrency = Flag{Type: Int, Name: flagkey.FnConcurrency, Aliases: []string{"con"}, Usage: "Maximum number of pods specialized concurrently to serve requests", DefaultValue: 500} FnRequestsPerPod = Flag{Type: Int, Name: flagkey.FnRequestsPerPod, Aliases: []string{"rpp"}, Usage: "Maximum number of concurrent requests that can be served by a specialized pod", DefaultValue: 1} + FnOnceOnly = Flag{Type: Bool, Name: flagkey.FnOnceOnly, Aliases: []string{"yolo"}, Usage: "Specifies if specialized pod will serve exactly one request in its lifetime"} HtName = Flag{Type: String, Name: flagkey.HtName, Usage: "HTTP trigger name"} HtMethod = Flag{Type: String, Name: flagkey.HtMethod, Usage: "HTTP Method: GET|POST|PUT|DELETE|HEAD", DefaultValue: http.MethodGet} diff --git a/pkg/fission-cli/flag/key/key.go b/pkg/fission-cli/flag/key/key.go index dfd8e5f7a..8d4caaab1 100644 --- a/pkg/fission-cli/flag/key/key.go +++ b/pkg/fission-cli/flag/key/key.go @@ -65,6 +65,7 @@ const ( FnIdleTimeout = "idletimeout" FnConcurrency = "concurrency" FnRequestsPerPod = "requestsperpod" + FnOnceOnly = "onceonly" HtName = resourceName HtMethod = "method"