faas/watchdog/readconfig.go
Sargun Dhillon b019f6ca54 Add Concurrency Limiter
This enables limiting concurrency. It is a naive approach which
will reject requests as soon as they exceed the maximum number
of in-flight requests.

It is a port of the following PR from the new watchdog code:
https://github.com/openfaas-incubator/of-watchdog/pull/54

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Signed-off-by: Lucas Roesler <roesler.lucas@gmail.com>
2019-06-16 15:23:20 +01:00

148 lines
3.5 KiB
Go

// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
package main
import (
"strconv"
"time"
)
// HasEnv provides interface for os.Getenv
type HasEnv interface {
Getenv(key string) string
}
// ReadConfig constitutes config from env variables
type ReadConfig struct {
}
func isBoolValueSet(val string) bool {
return len(val) > 0
}
func parseBoolValue(val string) bool {
if val == "true" {
return true
}
return false
}
func parseIntOrDurationValue(val string, fallback time.Duration) time.Duration {
if len(val) > 0 {
parsedVal, parseErr := strconv.Atoi(val)
if parseErr == nil && parsedVal >= 0 {
return time.Duration(parsedVal) * time.Second
}
}
duration, durationErr := time.ParseDuration(val)
if durationErr != nil {
return fallback
}
return duration
}
func parseIntValue(val string, fallback int) int {
if len(val) > 0 {
parsedVal, parseErr := strconv.Atoi(val)
if parseErr == nil && parsedVal >= 0 {
return parsedVal
}
}
return fallback
}
// Read fetches config from environmental variables.
func (ReadConfig) Read(hasEnv HasEnv) WatchdogConfig {
cfg := WatchdogConfig{
writeDebug: false,
cgiHeaders: true,
combineOutput: true,
}
cfg.faasProcess = hasEnv.Getenv("fprocess")
cfg.readTimeout = parseIntOrDurationValue(hasEnv.Getenv("read_timeout"), time.Second*5)
cfg.writeTimeout = parseIntOrDurationValue(hasEnv.Getenv("write_timeout"), time.Second*5)
cfg.execTimeout = parseIntOrDurationValue(hasEnv.Getenv("exec_timeout"), time.Second*0)
cfg.port = parseIntValue(hasEnv.Getenv("port"), 8080)
writeDebugEnv := hasEnv.Getenv("write_debug")
if isBoolValueSet(writeDebugEnv) {
cfg.writeDebug = parseBoolValue(writeDebugEnv)
}
cgiHeadersEnv := hasEnv.Getenv("cgi_headers")
if isBoolValueSet(cgiHeadersEnv) {
cfg.cgiHeaders = parseBoolValue(cgiHeadersEnv)
}
cfg.marshalRequest = parseBoolValue(hasEnv.Getenv("marshal_request"))
cfg.debugHeaders = parseBoolValue(hasEnv.Getenv("debug_headers"))
cfg.suppressLock = parseBoolValue(hasEnv.Getenv("suppress_lock"))
cfg.contentType = hasEnv.Getenv("content_type")
if isBoolValueSet(hasEnv.Getenv("combine_output")) {
cfg.combineOutput = parseBoolValue(hasEnv.Getenv("combine_output"))
}
cfg.metricsPort = 8081
cfg.maxInflight = parseIntValue(hasEnv.Getenv("max_inflight"), 0)
return cfg
}
// WatchdogConfig for the process.
type WatchdogConfig struct {
// HTTP read timeout
readTimeout time.Duration
// HTTP write timeout
writeTimeout time.Duration
// faasProcess is the process to exec
faasProcess string
// duration until the faasProcess will be killed
execTimeout time.Duration
// writeDebug write console stdout statements to the container
writeDebug bool
// marshal header and body via JSON
marshalRequest bool
// cgiHeaders will make environmental variables available with all the HTTP headers.
cgiHeaders bool
// prints out all incoming and out-going HTTP headers
debugHeaders bool
// Don't write a lock file to /tmp/
suppressLock bool
// contentType forces a specific pre-defined value for all responses
contentType string
// port for HTTP server
port int
// combineOutput combines stderr and stdout in response
combineOutput bool
// metricsPort is the HTTP port to serve metrics on
metricsPort int
// maxInflight limits the number of simultaneous
// requests that the watchdog allows concurrently.
// Any request which exceeds this limit will
// have an immediate response of 429.
maxInflight int
}