mirror of https://github.com/knative/caching.git
Auto-update dependencies (#65)
Produced via: `dep ensure -update knative.dev/test-infra knative.dev/pkg` /assign @mattmoor
This commit is contained in:
parent
caf670d252
commit
9dbdb2f91c
|
@ -927,7 +927,7 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:109be9502d5b6e9be46426641dd7f7b1328788d85cd22f314ac812489d874f30"
|
||||
digest = "1:bb229ac008f2b7ddcd122f857584627de4cf78f31f3001ca79560f48659db88f"
|
||||
name = "knative.dev/pkg"
|
||||
packages = [
|
||||
"apis",
|
||||
|
@ -946,7 +946,7 @@
|
|||
"metrics/metricskey",
|
||||
]
|
||||
pruneopts = "T"
|
||||
revision = "e8df94bc5a75081fe081548c261203467448857b"
|
||||
revision = "2b848f71969c997809a2dbea8351eaadb23e9bc9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -957,7 +957,7 @@
|
|||
"tools/dep-collector",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a6aed31ed1097dbfaaf1d056b5d89499f64c7235"
|
||||
revision = "becadcabaeced051dc3d95bde982c24fce37d78c"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
|
|
|
@ -289,6 +289,14 @@
|
|||
revision = "7c29201646fa3de8506f701213473dd407f19646"
|
||||
version = "v0.3.7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:aa0434674a14402891f31f393b4dd53792bc67eee05158748d999096a8826ed3"
|
||||
name = "github.com/influxdata/tdigest"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "bf2b5ad3c0a925c44a0d2842c5d8182113cd248e"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1f2aebae7e7c856562355ec0198d8ca2fa222fb05e5b1b66632a1fce39631885"
|
||||
name = "github.com/jmespath/go-jmespath"
|
||||
|
@ -311,6 +319,18 @@
|
|||
pruneopts = "NUT"
|
||||
revision = "f2b4162afba35581b6d4a50d3b8f34e33c144682"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:927762c6729b4e72957ba3310e485ed09cf8451c5a637a52fd016a9fe09e7936"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
"buffer",
|
||||
"jlexer",
|
||||
"jwriter",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b2ccc519800e761ac8000b95e5d57c80a897ff9e"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:56dbf15e091bf7926cb33a57cb6bdfc658fc6d3498d2f76f10a97ce7856f1fde"
|
||||
name = "github.com/markbates/inflect"
|
||||
|
@ -462,6 +482,14 @@
|
|||
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
|
||||
version = "v1.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:25bec9bd4bd740f94fcbd977bff20ca1b43a658645577ca8a705e639aba1eea4"
|
||||
name = "github.com/tsenart/vegeta"
|
||||
packages = ["lib"]
|
||||
pruneopts = "NUT"
|
||||
revision = "b5f4fca92137581c0f118ba6b106ba0cb3a2c84e"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0e3fd52087079d1289983e4fef32268ca965973f5370b69204e2934185527baa"
|
||||
name = "go.opencensus.io"
|
||||
|
@ -1157,6 +1185,7 @@
|
|||
"github.com/pkg/errors",
|
||||
"github.com/rogpeppe/go-internal/semver",
|
||||
"github.com/spf13/pflag",
|
||||
"github.com/tsenart/vegeta/lib",
|
||||
"go.opencensus.io/plugin/ochttp",
|
||||
"go.opencensus.io/plugin/ochttp/propagation/b3",
|
||||
"go.opencensus.io/stats",
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
|
@ -67,6 +68,17 @@ func GetConfig(masterURL, kubeconfig string) (*rest.Config, error) {
|
|||
return nil, fmt.Errorf("could not create a valid kubeconfig")
|
||||
}
|
||||
|
||||
// GetLoggingConfig gets the logging config from either the file system if present
|
||||
// or via reading a configMap from the API.
|
||||
// The context is expected to be initialized with injection.
|
||||
func GetLoggingConfig(ctx context.Context) (*logging.Config, error) {
|
||||
loggingConfigMap, err := kubeclient.Get(ctx).CoreV1().ConfigMaps(system.Namespace()).Get(logging.ConfigMapName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return logging.NewConfigFromConfigMap(loggingConfigMap)
|
||||
}
|
||||
|
||||
func Main(component string, ctors ...injection.ControllerConstructor) {
|
||||
// Set up signals so we handle the first shutdown signal gracefully.
|
||||
MainWithContext(signals.NewContext(), component, ctors...)
|
||||
|
@ -87,23 +99,10 @@ func MainWithContext(ctx context.Context, component string, ctors ...injection.C
|
|||
}
|
||||
|
||||
func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, ctors ...injection.ControllerConstructor) {
|
||||
// Set up our logger.
|
||||
loggingConfigMap, err := configmap.Load("/etc/config-logging")
|
||||
if err != nil {
|
||||
log.Fatal("Error loading logging configuration:", err)
|
||||
}
|
||||
loggingConfig, err := logging.NewConfigFromMap(loggingConfigMap)
|
||||
if err != nil {
|
||||
log.Fatal("Error parsing logging configuration:", err)
|
||||
}
|
||||
logger, atomicLevel := logging.NewLoggerFromConfig(loggingConfig, component)
|
||||
defer flush(logger)
|
||||
ctx = logging.WithLogger(ctx, logger)
|
||||
|
||||
logger.Infof("Registering %d clients", len(injection.Default.GetClients()))
|
||||
logger.Infof("Registering %d informer factories", len(injection.Default.GetInformerFactories()))
|
||||
logger.Infof("Registering %d informers", len(injection.Default.GetInformers()))
|
||||
logger.Infof("Registering %d controllers", len(ctors))
|
||||
log.Printf("Registering %d clients", len(injection.Default.GetClients()))
|
||||
log.Printf("Registering %d informer factories", len(injection.Default.GetInformerFactories()))
|
||||
log.Printf("Registering %d informers", len(injection.Default.GetInformers()))
|
||||
log.Printf("Registering %d controllers", len(ctors))
|
||||
|
||||
// Adjust our client's rate limits based on the number of controller's we are running.
|
||||
cfg.QPS = float32(len(ctors)) * rest.DefaultQPS
|
||||
|
@ -111,6 +110,15 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto
|
|||
|
||||
ctx, informers := injection.Default.SetupInformers(ctx, cfg)
|
||||
|
||||
// Set up our logger.
|
||||
loggingConfig, err := GetLoggingConfig(ctx)
|
||||
if err != nil {
|
||||
log.Fatal("Error reading/parsing logging configuration:", err)
|
||||
}
|
||||
logger, atomicLevel := logging.NewLoggerFromConfig(loggingConfig, component)
|
||||
defer flush(logger)
|
||||
ctx = logging.WithLogger(ctx, logger)
|
||||
|
||||
// TODO(mattmoor): This should itself take a context and be injection-based.
|
||||
cmw := configmap.NewInformedWatcher(kubeclient.Get(ctx), system.Namespace())
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright 2019 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pacers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
vegeta "github.com/tsenart/vegeta/lib"
|
||||
)
|
||||
|
||||
// combinedPacer is a Pacer that combines multiple Pacers and runs them sequentially when being used for attack.
|
||||
type combinedPacer struct {
|
||||
// pacers is a list of pacers that will be used sequentially for attack.
|
||||
// MUST have more than 1 pacer.
|
||||
pacers []vegeta.Pacer
|
||||
// durations is the list of durations for the given Pacers.
|
||||
// MUST have the same length as Pacers, and each duration MUST be longer than 1 second.
|
||||
durations []time.Duration
|
||||
|
||||
// totalDuration is sum of the given Durations.
|
||||
totalDuration uint64
|
||||
// stepDurations is the accumulative duration of each step calculated from the given Durations.
|
||||
stepDurations []uint64
|
||||
|
||||
curPacerIndex uint
|
||||
prevElapsedHits uint64
|
||||
prevElapsedTime uint64
|
||||
}
|
||||
|
||||
// NewCombined returns a new CombinedPacer with the given config.
|
||||
func NewCombined(pacers []vegeta.Pacer, durations []time.Duration) (vegeta.Pacer, error) {
|
||||
if len(pacers) == 0 || len(durations) == 0 || len(pacers) != len(durations) || len(pacers) == 1 {
|
||||
return nil, errors.New("configuration for this CombinedPacer is invalid")
|
||||
}
|
||||
|
||||
var totalDuration uint64
|
||||
var stepDurations = make([]uint64, len(pacers))
|
||||
for i, duration := range durations {
|
||||
if duration < 1*time.Second {
|
||||
return nil, errors.New("duration for each pacer must be longer than 1 second")
|
||||
}
|
||||
totalDuration += uint64(duration)
|
||||
if i == 0 {
|
||||
stepDurations[0] = uint64(duration)
|
||||
} else {
|
||||
stepDurations[i] = stepDurations[i-1] + uint64(duration)
|
||||
}
|
||||
}
|
||||
pacer := &combinedPacer{
|
||||
pacers: pacers,
|
||||
durations: durations,
|
||||
|
||||
totalDuration: totalDuration,
|
||||
stepDurations: stepDurations,
|
||||
}
|
||||
return pacer, nil
|
||||
}
|
||||
|
||||
// combinedPacer satisfies the Pacer interface.
|
||||
var _ vegeta.Pacer = &combinedPacer{}
|
||||
|
||||
// String returns a pretty-printed description of the combinedPacer's behaviour.
|
||||
func (cp *combinedPacer) String() string {
|
||||
var sb strings.Builder
|
||||
for i := range cp.pacers {
|
||||
sb.WriteString(fmt.Sprintf("Pacer: %s, Duration: %s\n", cp.pacers[i], cp.durations[i]))
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (cp *combinedPacer) Pace(elapsedTime time.Duration, elapsedHits uint64) (time.Duration, bool) {
|
||||
pacerTimeOffset := uint64(elapsedTime) % cp.totalDuration
|
||||
pacerIndex := cp.pacerIndex(pacerTimeOffset)
|
||||
|
||||
// If it needs to switch to the next pacer, update prevElapsedTime, prevElapsedHits and curPacerIndex.
|
||||
if pacerIndex != cp.curPacerIndex {
|
||||
cp.prevElapsedTime = uint64(elapsedTime)
|
||||
cp.prevElapsedHits = elapsedHits
|
||||
cp.curPacerIndex = pacerIndex
|
||||
}
|
||||
|
||||
// Use the adjusted elapsedTime and elapsedHits to get the time to wait for the next hit.
|
||||
curPacer := cp.pacers[cp.curPacerIndex]
|
||||
curElapsedTime := time.Duration(uint64(elapsedTime) - cp.prevElapsedTime)
|
||||
curElapsedHits := elapsedHits - cp.prevElapsedHits
|
||||
return curPacer.Pace(curElapsedTime, curElapsedHits)
|
||||
}
|
||||
|
||||
// pacerIndex returns the index of pacer that pacerTimeOffset falls into
|
||||
func (cp *combinedPacer) pacerIndex(pacerTimeOffset uint64) uint {
|
||||
i, j := 0, len(cp.stepDurations)
|
||||
for i < j {
|
||||
m := i + (j-i)/2
|
||||
if pacerTimeOffset >= cp.stepDurations[m] {
|
||||
i = m + 1
|
||||
} else {
|
||||
j = m
|
||||
}
|
||||
}
|
||||
return uint(i)
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright 2019 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pacers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
vegeta "github.com/tsenart/vegeta/lib"
|
||||
)
|
||||
|
||||
// steadyUpPacer is a Pacer that describes attack request rates that increases in the beginning then becomes steady.
|
||||
// Max | ,----------------
|
||||
// | /
|
||||
// | /
|
||||
// | /
|
||||
// | /
|
||||
// Min -+------------------------------> t
|
||||
// |<-Up->|
|
||||
type steadyUpPacer struct {
|
||||
// upDuration is the duration that attack request rates increase from Min to Max.
|
||||
// MUST be larger than 0.
|
||||
upDuration time.Duration
|
||||
// min is the attack request rates from the beginning.
|
||||
// MUST be larger than 0.
|
||||
min vegeta.Rate
|
||||
// max is the maximum and final steady attack request rates.
|
||||
// MUST be larger than Min.
|
||||
max vegeta.Rate
|
||||
|
||||
slope float64
|
||||
minHitsPerNs float64
|
||||
maxHitsPerNs float64
|
||||
}
|
||||
|
||||
// NewSteadyUp returns a new SteadyUpPacer with the given config.
|
||||
func NewSteadyUp(min vegeta.Rate, max vegeta.Rate, upDuration time.Duration) (vegeta.Pacer, error) {
|
||||
if upDuration <= 0 || min.Freq <= 0 || min.Per <= 0 || max.Freq <= 0 || max.Per <= 0 {
|
||||
return nil, errors.New("configuration for this SteadyUpPacer is invalid")
|
||||
}
|
||||
minHitsPerNs := hitsPerNs(min)
|
||||
maxHitsPerNs := hitsPerNs(max)
|
||||
if minHitsPerNs >= maxHitsPerNs {
|
||||
return nil, errors.New("min rate must be smaller than max rate for SteadyUpPacer")
|
||||
}
|
||||
|
||||
pacer := &steadyUpPacer{
|
||||
min: min,
|
||||
max: max,
|
||||
upDuration: upDuration,
|
||||
slope: (maxHitsPerNs - minHitsPerNs) / float64(upDuration),
|
||||
minHitsPerNs: minHitsPerNs,
|
||||
maxHitsPerNs: maxHitsPerNs,
|
||||
}
|
||||
return pacer, nil
|
||||
}
|
||||
|
||||
// steadyUpPacer satisfies the Pacer interface.
|
||||
var _ vegeta.Pacer = &steadyUpPacer{}
|
||||
|
||||
// String returns a pretty-printed description of the steadyUpPacer's behaviour.
|
||||
func (sup *steadyUpPacer) String() string {
|
||||
return fmt.Sprintf("Up{%s + %s / %s}, then Steady{%s}", sup.min, sup.max, sup.upDuration, sup.max)
|
||||
}
|
||||
|
||||
// Pace determines the length of time to sleep until the next hit is sent.
|
||||
func (sup *steadyUpPacer) Pace(elapsedTime time.Duration, elapsedHits uint64) (time.Duration, bool) {
|
||||
expectedHits := sup.hits(elapsedTime)
|
||||
if elapsedHits < uint64(expectedHits) {
|
||||
// Running behind, send next hit immediately.
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Re-arranging our hits equation to provide a duration given the number of
|
||||
// requests sent is non-trivial, so we must solve for the duration numerically.
|
||||
nsPerHit := 1 / sup.hitsPerNs(elapsedTime)
|
||||
hitsToWait := float64(elapsedHits+1) - expectedHits
|
||||
nextHitIn := time.Duration(nsPerHit * hitsToWait)
|
||||
|
||||
// If we can't converge to an error of <1e-3 within 10 iterations, bail.
|
||||
// This rarely even loops for any large Period if hitsToWait is small.
|
||||
for i := 0; i < 10; i++ {
|
||||
hitsAtGuess := sup.hits(elapsedTime + nextHitIn)
|
||||
err := float64(elapsedHits+1) - hitsAtGuess
|
||||
if math.Abs(err) < 1e-3 {
|
||||
return nextHitIn, false
|
||||
}
|
||||
nextHitIn = time.Duration(float64(nextHitIn) / (hitsAtGuess - float64(elapsedHits)))
|
||||
}
|
||||
|
||||
return nextHitIn, false
|
||||
}
|
||||
|
||||
// hits returns the number of expected hits for this pacer during the given time.
|
||||
func (sup *steadyUpPacer) hits(t time.Duration) float64 {
|
||||
// If t is smaller than the upDuration, calculate the hits as a trapezoid.
|
||||
if t <= sup.upDuration {
|
||||
curtHitsPerNs := sup.hitsPerNs(t)
|
||||
return (curtHitsPerNs + sup.minHitsPerNs) / 2.0 * float64(t)
|
||||
}
|
||||
|
||||
// If t is larger than the upDuration, calculate the hits as a trapezoid + a rectangle.
|
||||
upHits := (sup.maxHitsPerNs + sup.minHitsPerNs) / 2.0 * float64(sup.upDuration)
|
||||
steadyHits := sup.maxHitsPerNs * float64(t-sup.upDuration)
|
||||
return upHits + steadyHits
|
||||
}
|
||||
|
||||
// hitsPerNs returns the attack rate for this pacer at a given time.
|
||||
func (sup *steadyUpPacer) hitsPerNs(t time.Duration) float64 {
|
||||
if t <= sup.upDuration {
|
||||
return sup.minHitsPerNs + float64(t)*sup.slope
|
||||
}
|
||||
|
||||
return sup.maxHitsPerNs
|
||||
}
|
||||
|
||||
// hitsPerNs returns the attack rate this ConstantPacer represents, in
|
||||
// fractional hits per nanosecond.
|
||||
func hitsPerNs(cp vegeta.ConstantPacer) float64 {
|
||||
return float64(cp.Freq) / float64(cp.Per)
|
||||
}
|
Loading…
Reference in New Issue