mirror of https://github.com/knative/caching.git
upgrade to latest dependencies (#429)
bumping knative.dev/pkg 84c98f3...9039dc1: > 9039dc1 moved release docs to github.com/knative/release (# 2040) > 07b5ddf add demoteFunc controller option (# 2033) > 8a8de5f Move IsKProbe to drainer, since it's the only place it's used (# 2038) > 5367a43 Fix potential deadlock when k8s client is used (# 2031) > b5bf07b adding retry event count metric for source (# 2016) > 17a36e7 Format markdown (# 2037) > 29be1c1 Add the release badge for all of the repos (# 2035) > e90ac15 Remove the system.Clock and it's mock in a different location (# 2034) > 8a9bf76 Add symmetric filter helped based on OwnerRefable. (# 2032) > 29092fe Format markdown (# 2030) > d733bb4 Add nightly badged to release tables (# 2029) > 7b5bcc3 Use the constant for UserAgent (# 2028) > 86a8236 Format markdown (# 2025) > 6c2f94a Unregister views to avoid slow oom issue during meter cleanup (# 2005) > 7689cce Update common github actions (# 2024) > f4650d8 Add releasability badges for each repo (# 2023) > 584933f Format markdown (# 2022) Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
parent
d1dfa6451c
commit
ac5fcb4a9e
2
go.mod
2
go.mod
|
@ -18,5 +18,5 @@ require (
|
||||||
k8s.io/code-generator v0.19.7
|
k8s.io/code-generator v0.19.7
|
||||||
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6
|
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6
|
||||||
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf
|
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf
|
||||||
knative.dev/pkg v0.0.0-20210215165523-84c98f3c3e7a
|
knative.dev/pkg v0.0.0-20210226182947-9039dc189ced
|
||||||
)
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1188,8 +1188,8 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K
|
||||||
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf h1:u4cY4jr2LYvhoz/1HBWEPsMiLkm0HMdDTfmmw1RE8zE=
|
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf h1:u4cY4jr2LYvhoz/1HBWEPsMiLkm0HMdDTfmmw1RE8zE=
|
||||||
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||||
knative.dev/pkg v0.0.0-20210215165523-84c98f3c3e7a h1:Jb8iKzfqhqwYoK9xHulmFdoscUBPLlXmBQMb2grTa78=
|
knative.dev/pkg v0.0.0-20210226182947-9039dc189ced h1:OCtTbXsJhiR35qCDxFj9Xc8sU3i87ePbc7YlHCt0al4=
|
||||||
knative.dev/pkg v0.0.0-20210215165523-84c98f3c3e7a/go.mod h1:TJSdebQOWX5N2bszohOYVi0H1QtXbtlYLuMghAFBMhY=
|
knative.dev/pkg v0.0.0-20210226182947-9039dc189ced/go.mod h1:TJSdebQOWX5N2bszohOYVi0H1QtXbtlYLuMghAFBMhY=
|
||||||
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
|
|
|
@ -271,6 +271,9 @@ func NewImpl(ctx {{.contextContext|raw}}, r Interface{{if .hasClass}}, classValu
|
||||||
rec.skipStatusUpdates = true
|
rec.skipStatusUpdates = true
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
if opts.DemoteFunc != nil {
|
||||||
|
rec.DemoteFunc = opts.DemoteFunc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rec.Recorder = createRecorder(ctx, agentName)
|
rec.Recorder = createRecorder(ctx, agentName)
|
||||||
|
|
|
@ -363,6 +363,9 @@ func NewReconciler(ctx {{.contextContext|raw}}, logger *{{.zapSugaredLogger|raw}
|
||||||
rec.skipStatusUpdates = true
|
rec.skipStatusUpdates = true
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
if opts.DemoteFunc != nil {
|
||||||
|
rec.DemoteFunc = opts.DemoteFunc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rec
|
return rec
|
||||||
|
|
|
@ -152,6 +152,13 @@ func FilterControllerGK(gk schema.GroupKind) func(obj interface{}) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterController makes it simple to create FilterFunc's for use with
|
||||||
|
// cache.FilteringResourceEventHandler that filter based on the
|
||||||
|
// controlling resource.
|
||||||
|
func FilterController(r kmeta.OwnerRefable) func(obj interface{}) bool {
|
||||||
|
return FilterControllerGK(r.GetGroupVersionKind().GroupKind())
|
||||||
|
}
|
||||||
|
|
||||||
// FilterWithName makes it simple to create FilterFunc's for use with
|
// FilterWithName makes it simple to create FilterFunc's for use with
|
||||||
// cache.FilteringResourceEventHandler that filter based on a name.
|
// cache.FilteringResourceEventHandler that filter based on a name.
|
||||||
func FilterWithName(name string) func(obj interface{}) bool {
|
func FilterWithName(name string) func(obj interface{}) bool {
|
||||||
|
|
|
@ -35,6 +35,9 @@ type Options struct {
|
||||||
// SkipStatusUpdates configures this reconciler to either do automated status
|
// SkipStatusUpdates configures this reconciler to either do automated status
|
||||||
// updates (default) or skip them if this is set to true.
|
// updates (default) or skip them if this is set to true.
|
||||||
SkipStatusUpdates bool
|
SkipStatusUpdates bool
|
||||||
|
|
||||||
|
// DemoteFunc configures the demote function this reconciler uses
|
||||||
|
DemoteFunc func(b reconciler.Bucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OptionsFn is a callback method signature that accepts an Impl and returns
|
// OptionsFn is a callback method signature that accepts an Impl and returns
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"go.opencensus.io/resource"
|
"go.opencensus.io/resource"
|
||||||
"go.opencensus.io/stats/view"
|
"go.opencensus.io/stats/view"
|
||||||
|
@ -32,9 +31,14 @@ import (
|
||||||
var (
|
var (
|
||||||
curMetricsExporter view.Exporter
|
curMetricsExporter view.Exporter
|
||||||
curMetricsConfig *metricsConfig
|
curMetricsConfig *metricsConfig
|
||||||
metricsMux sync.RWMutex
|
mWorker *metricsWorker
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
mWorker = newMetricsWorker()
|
||||||
|
go mWorker.start()
|
||||||
|
}
|
||||||
|
|
||||||
// SecretFetcher is a function (extracted from SecretNamespaceLister) for fetching
|
// SecretFetcher is a function (extracted from SecretNamespaceLister) for fetching
|
||||||
// a specific Secret. This avoids requiring global or namespace list in controllers.
|
// a specific Secret. This avoids requiring global or namespace list in controllers.
|
||||||
type SecretFetcher func(string) (*corev1.Secret, error)
|
type SecretFetcher func(string) (*corev1.Secret, error)
|
||||||
|
@ -154,29 +158,15 @@ func UpdateExporter(ctx context.Context, ops ExporterOptions, logger *zap.Sugare
|
||||||
|
|
||||||
// Updating the metrics config and the metrics exporters needs to be atomic to
|
// Updating the metrics config and the metrics exporters needs to be atomic to
|
||||||
// avoid using an outdated metrics config with new exporters.
|
// avoid using an outdated metrics config with new exporters.
|
||||||
metricsMux.Lock()
|
updateCmd := &updateMetricsConfigWithExporter{
|
||||||
defer metricsMux.Unlock()
|
ctx: ctx,
|
||||||
|
newConfig: newConfig,
|
||||||
if isNewExporterRequired(newConfig) {
|
done: make(chan error),
|
||||||
logger.Info("Flushing the existing exporter before setting up the new exporter.")
|
}
|
||||||
flushGivenExporter(curMetricsExporter)
|
mWorker.c <- updateCmd
|
||||||
e, f, err := newMetricsExporter(newConfig, logger)
|
err = <-updateCmd.done
|
||||||
if err != nil {
|
|
||||||
logger.Errorw("Failed to update a new metrics exporter based on metric config", zap.Error(err), "config", newConfig)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
existingConfig := curMetricsConfig
|
|
||||||
curMetricsExporter = e
|
|
||||||
if err := setFactory(f); err != nil {
|
|
||||||
logger.Errorw("Failed to update metrics factory when loading metric config", zap.Error(err), "config", newConfig)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Infof("Successfully updated the metrics exporter; old config: %v; new config %v", existingConfig, newConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
setCurMetricsConfigUnlocked(newConfig)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// isNewExporterRequired compares the non-nil newConfig against curMetricsConfig. When backend changes,
|
// isNewExporterRequired compares the non-nil newConfig against curMetricsConfig. When backend changes,
|
||||||
// or stackdriver project ID changes for stackdriver backend, we need to update the metrics exporter.
|
// or stackdriver project ID changes for stackdriver backend, we need to update the metrics exporter.
|
||||||
|
@ -228,27 +218,35 @@ func newMetricsExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCurMetricsExporter() view.Exporter {
|
func getCurMetricsExporter() view.Exporter {
|
||||||
metricsMux.RLock()
|
readCmd := &readExporter{done: make(chan *view.Exporter)}
|
||||||
defer metricsMux.RUnlock()
|
mWorker.c <- readCmd
|
||||||
return curMetricsExporter
|
e := <-readCmd.done
|
||||||
|
return *e
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCurMetricsExporter(e view.Exporter) {
|
func setCurMetricsExporter(e view.Exporter) {
|
||||||
metricsMux.Lock()
|
setCmd := &setExporter{
|
||||||
defer metricsMux.Unlock()
|
newExporter: &e,
|
||||||
curMetricsExporter = e
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
mWorker.c <- setCmd
|
||||||
|
<-setCmd.done
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCurMetricsConfig() *metricsConfig {
|
func getCurMetricsConfig() *metricsConfig {
|
||||||
metricsMux.RLock()
|
readCmd := &readMetricsConfig{done: make(chan *metricsConfig)}
|
||||||
defer metricsMux.RUnlock()
|
mWorker.c <- readCmd
|
||||||
return curMetricsConfig
|
cfg := <-readCmd.done
|
||||||
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCurMetricsConfig(c *metricsConfig) {
|
func setCurMetricsConfig(c *metricsConfig) {
|
||||||
metricsMux.Lock()
|
setCmd := &setMetricsConfig{
|
||||||
defer metricsMux.Unlock()
|
newConfig: c,
|
||||||
setCurMetricsConfigUnlocked(c)
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
mWorker.c <- setCmd
|
||||||
|
<-setCmd.done
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCurMetricsConfigUnlocked(c *metricsConfig) {
|
func setCurMetricsConfigUnlocked(c *metricsConfig) {
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 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 metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"go.opencensus.io/stats/view"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"knative.dev/pkg/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
type metricsWorker struct {
|
||||||
|
c chan command
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMetricsWorker() *metricsWorker {
|
||||||
|
return &metricsWorker{c: make(chan command)}
|
||||||
|
}
|
||||||
|
|
||||||
|
type command interface {
|
||||||
|
handleCommand(w *metricsWorker)
|
||||||
|
}
|
||||||
|
|
||||||
|
type readExporter struct {
|
||||||
|
done chan *view.Exporter
|
||||||
|
}
|
||||||
|
|
||||||
|
type setExporter struct {
|
||||||
|
newExporter *view.Exporter
|
||||||
|
done chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type readMetricsConfig struct {
|
||||||
|
done chan *metricsConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type updateMetricsConfigWithExporter struct {
|
||||||
|
ctx context.Context
|
||||||
|
newConfig *metricsConfig
|
||||||
|
done chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
type setMetricsConfig struct {
|
||||||
|
newConfig *metricsConfig
|
||||||
|
done chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *readMetricsConfig) handleCommand(w *metricsWorker) {
|
||||||
|
cmd.done <- curMetricsConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *setMetricsConfig) handleCommand(w *metricsWorker) {
|
||||||
|
setCurMetricsConfigUnlocked(cmd.newConfig)
|
||||||
|
cmd.done <- struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *updateMetricsConfigWithExporter) handleCommand(w *metricsWorker) {
|
||||||
|
ctx := cmd.ctx
|
||||||
|
logger := logging.FromContext(ctx)
|
||||||
|
if isNewExporterRequired(cmd.newConfig) {
|
||||||
|
logger.Info("Flushing the existing exporter before setting up the new exporter.")
|
||||||
|
flushGivenExporter(curMetricsExporter)
|
||||||
|
e, f, err := newMetricsExporter(cmd.newConfig, logger)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorw("Failed to update a new metrics exporter based on metric config", zap.Error(err), "config", cmd.newConfig)
|
||||||
|
cmd.done <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
existingConfig := curMetricsConfig
|
||||||
|
curMetricsExporter = e
|
||||||
|
if err := setFactory(f); err != nil {
|
||||||
|
logger.Errorw("Failed to update metrics factory when loading metric config", zap.Error(err), "config", cmd.newConfig)
|
||||||
|
cmd.done <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Infof("Successfully updated the metrics exporter; old config: %v; new config %v", existingConfig, cmd.newConfig)
|
||||||
|
}
|
||||||
|
setCurMetricsConfigUnlocked(cmd.newConfig)
|
||||||
|
cmd.done <- nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *metricsWorker) start() {
|
||||||
|
for {
|
||||||
|
cmd := <-w.c
|
||||||
|
cmd.handleCommand(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *setExporter) handleCommand(w *metricsWorker) {
|
||||||
|
curMetricsExporter = *cmd.newExporter
|
||||||
|
cmd.done <- struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *readExporter) handleCommand(w *metricsWorker) {
|
||||||
|
cmd.done <- &curMetricsExporter
|
||||||
|
}
|
|
@ -82,10 +82,16 @@ func cleanup() {
|
||||||
expiryCutoff := allMeters.clock.Now().Add(-1 * maxMeterExporterAge)
|
expiryCutoff := allMeters.clock.Now().Add(-1 * maxMeterExporterAge)
|
||||||
allMeters.lock.Lock()
|
allMeters.lock.Lock()
|
||||||
defer allMeters.lock.Unlock()
|
defer allMeters.lock.Unlock()
|
||||||
|
resourceViews.lock.Lock()
|
||||||
|
defer resourceViews.lock.Unlock()
|
||||||
for key, meter := range allMeters.meters {
|
for key, meter := range allMeters.meters {
|
||||||
if key != "" && meter.t.Before(expiryCutoff) {
|
if key != "" && meter.t.Before(expiryCutoff) {
|
||||||
flushGivenExporter(meter.e)
|
flushGivenExporter(meter.e)
|
||||||
|
// Make a copy of views to avoid data races
|
||||||
|
viewsCopy := copyViews(resourceViews.views)
|
||||||
|
meter.m.Unregister(viewsCopy...)
|
||||||
delete(allMeters.meters, key)
|
delete(allMeters.meters, key)
|
||||||
|
meter.m.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +145,7 @@ func RegisterResourceView(views ...*view.View) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnregisterResourceView is similar to view.Unregiste(), except that it will
|
// UnregisterResourceView is similar to view.Unregister(), except that it will
|
||||||
// unregister the view across all Resources tracked byt he system, rather than
|
// unregister the view across all Resources tracked byt he system, rather than
|
||||||
// simply the default view.
|
// simply the default view.
|
||||||
func UnregisterResourceView(views ...*view.View) {
|
func UnregisterResourceView(views ...*view.View) {
|
||||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -52,33 +51,19 @@ const (
|
||||||
// uses to find out which version of the networking config is deployed.
|
// uses to find out which version of the networking config is deployed.
|
||||||
HashHeaderName = "K-Network-Hash"
|
HashHeaderName = "K-Network-Hash"
|
||||||
|
|
||||||
|
// KubeProbeUAPrefix is the prefix for the User-Agent header.
|
||||||
// Since K8s 1.8, prober requests have
|
// Since K8s 1.8, prober requests have
|
||||||
// User-Agent = "kube-probe/{major-version}.{minor-version}".
|
// User-Agent = "kube-probe/{major-version}.{minor-version}".
|
||||||
KubeProbeUAPrefix = "kube-probe/"
|
KubeProbeUAPrefix = "kube-probe/"
|
||||||
|
|
||||||
|
// KubeletProbeHeaderName is the header name to augment the probes, because
|
||||||
// Istio with mTLS rewrites probes, but their probes pass a different
|
// Istio with mTLS rewrites probes, but their probes pass a different
|
||||||
// user-agent. So we augment the probes with this header.
|
// user-agent.
|
||||||
KubeletProbeHeaderName = "K-Kubelet-Probe"
|
KubeletProbeHeaderName = "K-Kubelet-Probe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsKubeletProbe returns true if the request is a Kubernetes probe.
|
// IsKubeletProbe returns true if the request is a Kubernetes probe.
|
||||||
func IsKubeletProbe(r *http.Request) bool {
|
func IsKubeletProbe(r *http.Request) bool {
|
||||||
return strings.HasPrefix(r.Header.Get("User-Agent"), KubeProbeUAPrefix) ||
|
return strings.HasPrefix(r.Header.Get(UserAgentKey), KubeProbeUAPrefix) ||
|
||||||
r.Header.Get(KubeletProbeHeaderName) != ""
|
r.Header.Get(KubeletProbeHeaderName) != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsKProbe returns true if the request is a knatvie probe.
|
|
||||||
func IsKProbe(r *http.Request) bool {
|
|
||||||
return r.Header.Get(ProbeHeaderName) == ProbeHeaderValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServeKProbe serve KProbe requests.
|
|
||||||
func ServeKProbe(w http.ResponseWriter, r *http.Request) {
|
|
||||||
hh := r.Header.Get(HashHeaderName)
|
|
||||||
if hh == "" {
|
|
||||||
http.Error(w, fmt.Sprintf("a probe request must contain a non-empty %q header", HashHeaderName), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Header().Set(HashHeaderName, hh)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
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 system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Mockable interface for time based testing
|
|
||||||
type Clock interface {
|
|
||||||
Now() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type RealClock struct{}
|
|
||||||
|
|
||||||
func (RealClock) Now() time.Time {
|
|
||||||
return time.Now()
|
|
||||||
}
|
|
|
@ -658,7 +658,7 @@ k8s.io/utils/trace
|
||||||
# knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf
|
# knative.dev/hack v0.0.0-20210203173706-8368e1f6eacf
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/hack
|
knative.dev/hack
|
||||||
# knative.dev/pkg v0.0.0-20210215165523-84c98f3c3e7a
|
# knative.dev/pkg v0.0.0-20210226182947-9039dc189ced
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/pkg/apis
|
knative.dev/pkg/apis
|
||||||
knative.dev/pkg/apis/duck
|
knative.dev/pkg/apis/duck
|
||||||
|
|
Loading…
Reference in New Issue