Merge pull request #40606 from deads2k/client-17-sync
Automatic merge from submit-queue (batch tested with PRs 34543, 40606) sync client-go and move util/workqueue The vision of client-go is that it provides enough utilities to build a reasonable controller. It has been copying `util/workqueue`. This makes it authoritative. @liggitt I'm getting really close to making client-go authoritative ptal. approved based on https://github.com/kubernetes/kubernetes/issues/40363
This commit is contained in:
@@ -62,7 +62,6 @@ go_library(
|
||||
"//pkg/genericapiserver/registry/generic/rest:go_default_library",
|
||||
"//pkg/genericapiserver/registry/rest:go_default_library",
|
||||
"//pkg/genericapiserver/server:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
@@ -77,6 +76,7 @@ go_library(
|
||||
"//vendor:k8s.io/client-go/rest",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/transport",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -26,8 +26,8 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
|
||||
informers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion"
|
||||
|
@@ -27,7 +27,6 @@ go_library(
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -36,6 +35,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/flowcontrol",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
fed "k8s.io/kubernetes/federation/apis/federation"
|
||||
fedv1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
@@ -46,7 +47,6 @@ import (
|
||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -28,7 +28,6 @@ go_library(
|
||||
"//pkg/client/legacylisters:go_default_library",
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -37,6 +36,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/flowcontrol",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
fed "k8s.io/kubernetes/federation/apis/federation"
|
||||
fedv1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
@@ -47,7 +48,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/client/legacylisters"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -33,7 +33,6 @@ go_library(
|
||||
"//pkg/client/legacylisters:go_default_library",
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -45,6 +44,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/rest",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -25,11 +25,11 @@ import (
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/client/legacylisters"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"reflect"
|
||||
|
||||
|
@@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
federationcache "k8s.io/kubernetes/federation/client/cache"
|
||||
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
@@ -46,7 +47,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/client/legacylisters"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -237,7 +237,6 @@ pkg/util/validation
|
||||
pkg/util/validation/field
|
||||
pkg/util/version
|
||||
pkg/util/wait
|
||||
pkg/util/workqueue
|
||||
pkg/util/yaml
|
||||
pkg/version/prometheus
|
||||
pkg/volume
|
||||
@@ -299,6 +298,7 @@ staging/src/k8s.io/client-go/tools/auth
|
||||
staging/src/k8s.io/client-go/tools/metrics
|
||||
staging/src/k8s.io/client-go/util/cert
|
||||
staging/src/k8s.io/client-go/util/homedir
|
||||
staging/src/k8s.io/client-go/util/workqueue
|
||||
test/e2e/perftype
|
||||
test/e2e_node/runner/local
|
||||
test/images/clusterapi-tester
|
||||
|
@@ -26,7 +26,6 @@ go_library(
|
||||
"//pkg/client/legacylisters:go_default_library",
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/cloudflare/cfssl/config",
|
||||
"//vendor:github.com/cloudflare/cfssl/helpers",
|
||||
"//vendor:github.com/cloudflare/cfssl/signer",
|
||||
@@ -38,6 +37,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -26,13 +26,13 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
certificates "k8s.io/kubernetes/pkg/apis/certificates/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
|
||||
"k8s.io/kubernetes/pkg/client/legacylisters"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@@ -27,7 +27,6 @@ go_library(
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library",
|
||||
"//plugin/pkg/scheduler/schedulercache:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
@@ -37,6 +36,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -29,6 +29,7 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
@@ -40,7 +41,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"
|
||||
|
||||
|
@@ -32,7 +32,6 @@ go_library(
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/util/labels:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/equality",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
@@ -44,6 +43,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/integer",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -36,6 +36,7 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
@@ -46,7 +47,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -25,7 +25,6 @@ go_library(
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/intstr:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||
@@ -34,6 +33,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -52,10 +52,10 @@ go_test(
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/intstr:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/uuid",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -28,6 +28,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
@@ -40,7 +41,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@@ -26,6 +26,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||
@@ -35,7 +36,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
type pdbStates map[string]policy.PodDisruptionBudget
|
||||
|
@@ -24,7 +24,6 @@ go_library(
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -35,6 +34,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -31,6 +31,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/api/v1/endpoints"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
@@ -40,7 +41,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@@ -21,7 +21,6 @@ go_library(
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/controller/garbagecollector/metaonly:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/golang/groupcache/lru",
|
||||
"//vendor:github.com/prometheus/client_golang/prometheus",
|
||||
@@ -41,6 +40,7 @@ go_library(
|
||||
"//vendor:k8s.io/client-go/kubernetes",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/clock",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -54,7 +54,6 @@ go_test(
|
||||
"//pkg/api/install:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/controller/garbagecollector/metaonly:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/stretchr/testify/assert",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||
@@ -65,6 +64,7 @@ go_test(
|
||||
"//vendor:k8s.io/client-go/dynamic",
|
||||
"//vendor:k8s.io/client-go/rest",
|
||||
"//vendor:k8s.io/client-go/util/clock",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -38,9 +38,9 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/clock"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
// import known versions
|
||||
_ "k8s.io/client-go/kubernetes"
|
||||
|
@@ -36,10 +36,10 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/util/clock"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
func TestNewGarbageCollector(t *testing.T) {
|
||||
|
@@ -27,13 +27,13 @@ go_library(
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -28,6 +28,7 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
batch "k8s.io/kubernetes/pkg/apis/batch/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
@@ -38,7 +39,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@@ -21,7 +21,6 @@ go_library(
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -35,6 +34,7 @@ go_library(
|
||||
"//vendor:k8s.io/client-go/discovery",
|
||||
"//vendor:k8s.io/client-go/dynamic",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -28,11 +28,11 @@ import (
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@@ -28,7 +28,6 @@ go_library(
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -38,6 +37,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -34,6 +34,7 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
@@ -44,7 +45,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -25,7 +25,6 @@ go_library(
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -36,6 +35,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apiserver/pkg/util/trace",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -34,6 +34,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
|
||||
@@ -42,7 +43,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -25,7 +25,6 @@ go_library(
|
||||
"//pkg/quota:go_default_library",
|
||||
"//pkg/quota/evaluator/core:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/equality",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
||||
@@ -36,6 +35,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -29,13 +29,13 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
// ResourceQuotaControllerOptions holds options for creating a quota controller
|
||||
|
@@ -24,7 +24,6 @@ go_library(
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
@@ -34,6 +33,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
|
||||
@@ -41,7 +42,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -31,7 +31,6 @@ go_library(
|
||||
"//pkg/registry/core/serviceaccount/storage:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
||||
@@ -47,6 +46,7 @@ go_library(
|
||||
"//vendor:k8s.io/apiserver/pkg/endpoints/request",
|
||||
"//vendor:k8s.io/apiserver/pkg/storage/storagebackend",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -28,12 +28,12 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/client/legacylisters"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
// nameIndexFunc is an index function that indexes based on an object's name
|
||||
|
@@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
@@ -40,7 +41,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/registry/core/secret"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
// RemoveTokenBackoff is the recommended (empirical) retry interval for removing
|
||||
|
@@ -29,7 +29,6 @@ go_library(
|
||||
"//pkg/client/legacylisters:go_default_library",
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:gopkg.in/inf.v0",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
@@ -43,6 +42,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -36,8 +36,8 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
@@ -30,7 +30,6 @@ go_library(
|
||||
"//pkg/util/goroutinemap:go_default_library",
|
||||
"//pkg/util/io:go_default_library",
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
@@ -42,6 +41,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
|
||||
@@ -32,7 +33,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/util/goroutinemap"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
vol "k8s.io/kubernetes/pkg/volume"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@@ -28,6 +28,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
|
||||
@@ -37,7 +38,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/util/goroutinemap"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
vol "k8s.io/kubernetes/pkg/volume"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@@ -98,7 +98,7 @@ filegroup(
|
||||
"//pkg/util/validation:all-srcs",
|
||||
"//pkg/util/version:all-srcs",
|
||||
"//pkg/util/wait:all-srcs",
|
||||
"//pkg/util/workqueue:all-srcs",
|
||||
"//pkg/util/workqueue/prometheus:all-srcs",
|
||||
"//pkg/util/yaml:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
@@ -1,69 +0,0 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"default_rate_limiters.go",
|
||||
"delaying_queue.go",
|
||||
"doc.go",
|
||||
"metrics.go",
|
||||
"parallelizer.go",
|
||||
"queue.go",
|
||||
"rate_limitting_queue.go",
|
||||
"timed_queue.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor:github.com/juju/ratelimit",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
||||
"//vendor:k8s.io/client-go/util/clock",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"default_rate_limiters_test.go",
|
||||
"delaying_queue_test.go",
|
||||
"rate_limitting_queue_test.go",
|
||||
"timed_queue_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
"//vendor:k8s.io/client-go/util/clock",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["queue_test.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["//pkg/util/workqueue:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/util/workqueue/prometheus:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes 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 workqueue provides a simple queue that supports the following
|
||||
// features:
|
||||
// * Fair: items processed in the order in which they are added.
|
||||
// * Stingy: a single item will not be processed multiple times concurrently,
|
||||
// and if an item is added multiple times before it can be processed, it
|
||||
// will only be processed once.
|
||||
// * Multiple consumers and producers. In particular, it is allowed for an
|
||||
// item to be reenqueued while it is being processed.
|
||||
// * Shutdown notifications.
|
||||
package workqueue // import "k8s.io/kubernetes/pkg/util/workqueue"
|
@@ -12,8 +12,8 @@ go_library(
|
||||
srcs = ["prometheus.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//vendor:github.com/prometheus/client_golang/prometheus",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes 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 workqueue_test
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
)
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
// If something is seriously wrong this test will never complete.
|
||||
q := workqueue.New()
|
||||
|
||||
// Start producers
|
||||
const producers = 50
|
||||
producerWG := sync.WaitGroup{}
|
||||
producerWG.Add(producers)
|
||||
for i := 0; i < producers; i++ {
|
||||
go func(i int) {
|
||||
defer producerWG.Done()
|
||||
for j := 0; j < 50; j++ {
|
||||
q.Add(i)
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Start consumers
|
||||
const consumers = 10
|
||||
consumerWG := sync.WaitGroup{}
|
||||
consumerWG.Add(consumers)
|
||||
for i := 0; i < consumers; i++ {
|
||||
go func(i int) {
|
||||
defer consumerWG.Done()
|
||||
for {
|
||||
item, quit := q.Get()
|
||||
if item == "added after shutdown!" {
|
||||
t.Errorf("Got an item added after shutdown.")
|
||||
}
|
||||
if quit {
|
||||
return
|
||||
}
|
||||
t.Logf("Worker %v: begin processing %v", i, item)
|
||||
time.Sleep(3 * time.Millisecond)
|
||||
t.Logf("Worker %v: done processing %v", i, item)
|
||||
q.Done(item)
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
producerWG.Wait()
|
||||
q.ShutDown()
|
||||
q.Add("added after shutdown!")
|
||||
consumerWG.Wait()
|
||||
}
|
||||
|
||||
func TestAddWhileProcessing(t *testing.T) {
|
||||
q := workqueue.New()
|
||||
|
||||
// Start producers
|
||||
const producers = 50
|
||||
producerWG := sync.WaitGroup{}
|
||||
producerWG.Add(producers)
|
||||
for i := 0; i < producers; i++ {
|
||||
go func(i int) {
|
||||
defer producerWG.Done()
|
||||
q.Add(i)
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Start consumers
|
||||
const consumers = 10
|
||||
consumerWG := sync.WaitGroup{}
|
||||
consumerWG.Add(consumers)
|
||||
for i := 0; i < consumers; i++ {
|
||||
go func(i int) {
|
||||
defer consumerWG.Done()
|
||||
// Every worker will re-add every item up to two times.
|
||||
// This tests the dirty-while-processing case.
|
||||
counters := map[interface{}]int{}
|
||||
for {
|
||||
item, quit := q.Get()
|
||||
if quit {
|
||||
return
|
||||
}
|
||||
counters[item]++
|
||||
if counters[item] < 2 {
|
||||
q.Add(item)
|
||||
}
|
||||
q.Done(item)
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
producerWG.Wait()
|
||||
q.ShutDown()
|
||||
consumerWG.Wait()
|
||||
}
|
||||
|
||||
func TestLen(t *testing.T) {
|
||||
q := workqueue.New()
|
||||
q.Add("foo")
|
||||
if e, a := 1, q.Len(); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
q.Add("bar")
|
||||
if e, a := 2, q.Len(); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
q.Add("foo") // should not increase the queue length.
|
||||
if e, a := 2, q.Len(); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReinsert(t *testing.T) {
|
||||
q := workqueue.New()
|
||||
q.Add("foo")
|
||||
|
||||
// Start processing
|
||||
i, _ := q.Get()
|
||||
if i != "foo" {
|
||||
t.Errorf("Expected %v, got %v", "foo", i)
|
||||
}
|
||||
|
||||
// Add it back while processing
|
||||
q.Add(i)
|
||||
|
||||
// Finish it up
|
||||
q.Done(i)
|
||||
|
||||
// It should be back on the queue
|
||||
i, _ = q.Get()
|
||||
if i != "foo" {
|
||||
t.Errorf("Expected %v, got %v", "foo", i)
|
||||
}
|
||||
|
||||
// Finish that one up
|
||||
q.Done(i)
|
||||
|
||||
if a := q.Len(); a != 0 {
|
||||
t.Errorf("Expected queue to be empty. Has %v items", a)
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
func TestNoMemoryLeak(t *testing.T) {
|
||||
timedQueue := NewTimedWorkQueue()
|
||||
timedQueue.Add(&TimedWorkQueueItem{Object: &v1.Pod{}, StartTime: time.Time{}})
|
||||
item, _ := timedQueue.Get()
|
||||
timedQueue.Add(item)
|
||||
// The item should still be in the timedQueue.
|
||||
timedQueue.Done(item)
|
||||
item, _ = timedQueue.Get()
|
||||
timedQueue.Done(item)
|
||||
if len(timedQueue.Type.processing) != 0 {
|
||||
t.Errorf("expect timedQueue.Type.processing to be empty!")
|
||||
}
|
||||
}
|
@@ -24,7 +24,6 @@ go_library(
|
||||
"//pkg/quota:go_default_library",
|
||||
"//pkg/quota/install:go_default_library",
|
||||
"//pkg/storage/etcd:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//pkg/util/workqueue/prometheus:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/hashicorp/golang-lru",
|
||||
@@ -37,6 +36,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
"//vendor:k8s.io/apiserver/pkg/admission",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -30,9 +30,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
_ "k8s.io/kubernetes/pkg/util/workqueue/prometheus" // for workqueue metric registration
|
||||
)
|
||||
|
||||
|
@@ -22,7 +22,6 @@ go_library(
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
"//pkg/client/record:go_default_library",
|
||||
"//pkg/util/hash:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library",
|
||||
"//plugin/pkg/scheduler/api:go_default_library",
|
||||
@@ -39,6 +38,7 @@ go_library(
|
||||
"//vendor:k8s.io/apiserver/pkg/util/trace",
|
||||
"//vendor:k8s.io/client-go/rest",
|
||||
"//vendor:k8s.io/client-go/tools/cache",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -21,7 +21,6 @@ go_library(
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/client/legacylisters:go_default_library",
|
||||
"//pkg/kubelet/qos:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm/priorities/util:go_default_library",
|
||||
"//plugin/pkg/scheduler/schedulercache:go_default_library",
|
||||
@@ -29,6 +28,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/labels",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -29,10 +29,10 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/legacylisters"
|
||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
|
||||
priorityutil "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/util"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"
|
||||
|
@@ -28,7 +28,6 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm/priorities/util:go_default_library",
|
||||
@@ -38,6 +37,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/labels",
|
||||
"//vendor:k8s.io/client-go/util/workqueue",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -21,8 +21,8 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
|
||||
priorityutil "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/util"
|
||||
|
@@ -22,9 +22,9 @@ import (
|
||||
"github.com/golang/glog"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
utilnode "k8s.io/kubernetes/pkg/util/node"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
|
||||
schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"
|
||||
|
@@ -27,8 +27,8 @@ import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
utiltrace "k8s.io/apiserver/pkg/util/trace"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
|
||||
schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api"
|
||||
|
@@ -78,7 +78,7 @@ save "tools/cache"
|
||||
save "tools/clientcmd"
|
||||
save "tools/metrics"
|
||||
save "transport"
|
||||
save "pkg/third_party"
|
||||
save "third_party"
|
||||
save "plugin"
|
||||
save "util"
|
||||
|
||||
@@ -101,9 +101,6 @@ mkcp "/pkg/client/record" "/pkg/client"
|
||||
|
||||
mkcp "/pkg/client/unversioned/portforward" "/pkg/client/unversioned"
|
||||
|
||||
mkcp "/pkg/util/workqueue" "pkg/util"
|
||||
# remove this folder because it imports prometheus
|
||||
rm -rf "${CLIENT_REPO_TEMP}/pkg/util/workqueue/prometheus"
|
||||
# remove this test because it imports the internal clientset
|
||||
rm "${CLIENT_REPO_TEMP}"/pkg/client/unversioned/portforward/portforward_test.go
|
||||
|
||||
@@ -146,9 +143,6 @@ find "${CLIENT_REPO_TEMP}"/pkg/client/record -type f -name "*.go" -print0 | xarg
|
||||
find "${CLIENT_REPO_TEMP}"/pkg/client/record -type f -name "*.go" -print0 | xargs -0 sed -i 's,pkg/api",pkg/api/v1",g'
|
||||
# gofmt the changed files
|
||||
|
||||
echo "rewrite conflicting Prometheus registration"
|
||||
sed -i "s/kubernetes_build_info/kubernetes_build_info_copy/g" "${CLIENT_REPO_TEMP}"/pkg/version/version.go
|
||||
|
||||
echo "rewrite proto names in proto.RegisterType"
|
||||
find "${CLIENT_REPO_TEMP}" -type f -name "generated.pb.go" -print0 | xargs -0 sed -i "s/k8s\.io\.kubernetes/k8s.io.client-go/g"
|
||||
|
||||
|
86
staging/src/k8s.io/client-go/Godeps/Godeps.json
generated
86
staging/src/k8s.io/client-go/Godeps/Godeps.json
generated
@@ -324,151 +324,163 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/openapi",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/rand",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||
"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704"
|
||||
"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -375,6 +375,21 @@ func (m *APIResource) MarshalTo(data []byte) (int, error) {
|
||||
}
|
||||
i += n2
|
||||
}
|
||||
if len(m.ShortNames) > 0 {
|
||||
for _, s := range m.ShortNames {
|
||||
data[i] = 0x2a
|
||||
i++
|
||||
l = len(s)
|
||||
for l >= 1<<7 {
|
||||
data[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||
l >>= 7
|
||||
i++
|
||||
}
|
||||
data[i] = uint8(l)
|
||||
i++
|
||||
i += copy(data[i:], s)
|
||||
}
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
@@ -1470,6 +1485,12 @@ func (m *APIResource) Size() (n int) {
|
||||
l = m.Verbs.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
if len(m.ShortNames) > 0 {
|
||||
for _, s := range m.ShortNames {
|
||||
l = len(s)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@@ -1912,6 +1933,7 @@ func (this *APIResource) String() string {
|
||||
`Namespaced:` + fmt.Sprintf("%v", this.Namespaced) + `,`,
|
||||
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
|
||||
`Verbs:` + strings.Replace(fmt.Sprintf("%v", this.Verbs), "Verbs", "Verbs", 1) + `,`,
|
||||
`ShortNames:` + fmt.Sprintf("%v", this.ShortNames) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
@@ -2602,6 +2624,35 @@ func (m *APIResource) Unmarshal(data []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ShortNames", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ShortNames = append(m.ShortNames, string(data[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(data[iNdEx:])
|
||||
@@ -6649,136 +6700,137 @@ var (
|
||||
)
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 2089 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x19, 0x4d, 0x6f, 0x23, 0x49,
|
||||
0x35, 0xed, 0xc4, 0x1e, 0xfb, 0x39, 0xce, 0x47, 0x91, 0x01, 0x6f, 0x24, 0xec, 0x6c, 0xef, 0x0a,
|
||||
0xcd, 0xc2, 0xac, 0x4d, 0x02, 0xac, 0x86, 0x01, 0x06, 0xe2, 0x38, 0x13, 0x45, 0x3b, 0x99, 0x44,
|
||||
0x95, 0x9d, 0x41, 0x2c, 0x23, 0x44, 0xc7, 0x5d, 0x71, 0x9a, 0xb4, 0xbb, 0x9b, 0xaa, 0xb2, 0x27,
|
||||
0x61, 0x0f, 0xac, 0x04, 0x08, 0x0e, 0x08, 0xcd, 0x91, 0x03, 0x42, 0x3b, 0x82, 0x1b, 0x37, 0xfe,
|
||||
0x04, 0x73, 0x5c, 0x69, 0x2f, 0x1c, 0x90, 0xc5, 0x84, 0x03, 0x47, 0xee, 0x11, 0x07, 0x54, 0xd5,
|
||||
0x55, 0xfd, 0x61, 0xc7, 0x9b, 0x36, 0xbb, 0x87, 0x3d, 0xc5, 0xf5, 0xbe, 0xbf, 0xea, 0xbd, 0x57,
|
||||
0x1d, 0xd8, 0x3b, 0xbd, 0xc3, 0x1a, 0x8e, 0xdf, 0x3c, 0xed, 0x1f, 0x11, 0xea, 0x11, 0x4e, 0x58,
|
||||
0x73, 0x40, 0x3c, 0xdb, 0xa7, 0x4d, 0x85, 0xb0, 0x02, 0xa7, 0x67, 0x75, 0x4e, 0x1c, 0x8f, 0xd0,
|
||||
0xf3, 0x66, 0x70, 0xda, 0x15, 0x00, 0xd6, 0xec, 0x11, 0x6e, 0x35, 0x07, 0xeb, 0xcd, 0x2e, 0xf1,
|
||||
0x08, 0xb5, 0x38, 0xb1, 0x1b, 0x01, 0xf5, 0xb9, 0x8f, 0x5e, 0x0f, 0xb9, 0x1a, 0x49, 0xae, 0x46,
|
||||
0x70, 0xda, 0x15, 0x00, 0xd6, 0x10, 0x5c, 0x8d, 0xc1, 0xfa, 0xea, 0x9b, 0x5d, 0x87, 0x9f, 0xf4,
|
||||
0x8f, 0x1a, 0x1d, 0xbf, 0xd7, 0xec, 0xfa, 0x5d, 0xbf, 0x29, 0x99, 0x8f, 0xfa, 0xc7, 0xf2, 0x24,
|
||||
0x0f, 0xf2, 0x57, 0x28, 0x74, 0x75, 0xa2, 0x29, 0xb4, 0xef, 0x71, 0xa7, 0x47, 0x46, 0xad, 0x58,
|
||||
0x7d, 0xeb, 0x3a, 0x06, 0xd6, 0x39, 0x21, 0x3d, 0x6b, 0x8c, 0x6f, 0x63, 0x3c, 0x18, 0xca, 0xe3,
|
||||
0x26, 0x25, 0xcc, 0xef, 0xd3, 0xce, 0xb8, 0xae, 0xf5, 0xab, 0x79, 0xfa, 0xdc, 0x71, 0x9b, 0x8e,
|
||||
0xc7, 0x19, 0xa7, 0xa3, 0x2c, 0xe6, 0xdf, 0x66, 0xa1, 0xb8, 0x79, 0xb0, 0xbb, 0x43, 0xfd, 0x7e,
|
||||
0x80, 0xd6, 0x60, 0xce, 0xb3, 0x7a, 0xa4, 0x6a, 0xac, 0x19, 0xb7, 0x4a, 0xad, 0xf9, 0x17, 0xc3,
|
||||
0xfa, 0xcc, 0xc5, 0xb0, 0x3e, 0xf7, 0xd0, 0xea, 0x11, 0x2c, 0x31, 0xc8, 0x85, 0xe2, 0x80, 0x50,
|
||||
0xe6, 0xf8, 0x1e, 0xab, 0xe6, 0xd6, 0x66, 0x6f, 0x95, 0x37, 0xee, 0x35, 0xb2, 0x84, 0xb9, 0x21,
|
||||
0x15, 0x3c, 0x0e, 0x59, 0xef, 0xfb, 0xb4, 0xed, 0xb0, 0x8e, 0x3f, 0x20, 0xf4, 0xbc, 0xb5, 0xa4,
|
||||
0xb4, 0x14, 0x15, 0x92, 0xe1, 0x48, 0x03, 0xfa, 0xa5, 0x01, 0x4b, 0x01, 0x25, 0xc7, 0x84, 0x52,
|
||||
0x62, 0x2b, 0x7c, 0x75, 0x76, 0xcd, 0xf8, 0x14, 0xd4, 0x56, 0x95, 0xda, 0xa5, 0x83, 0x11, 0xf9,
|
||||
0x78, 0x4c, 0x23, 0xfa, 0x93, 0x01, 0xab, 0x8c, 0xd0, 0x01, 0xa1, 0x9b, 0xb6, 0x4d, 0x09, 0x63,
|
||||
0xad, 0xf3, 0x2d, 0xd7, 0x21, 0x1e, 0xdf, 0xda, 0x6d, 0x63, 0x56, 0x9d, 0x93, 0x71, 0xf8, 0x6e,
|
||||
0x36, 0x83, 0x0e, 0x27, 0xc9, 0x69, 0x99, 0xca, 0xa2, 0xd5, 0x89, 0x24, 0x0c, 0x7f, 0x8c, 0x19,
|
||||
0xe6, 0x31, 0xcc, 0xeb, 0x44, 0x3e, 0x70, 0x18, 0x47, 0x8f, 0xa1, 0xd0, 0x15, 0x07, 0x56, 0x35,
|
||||
0xa4, 0x81, 0x8d, 0x6c, 0x06, 0x6a, 0x19, 0xad, 0x05, 0x65, 0x4f, 0x41, 0x1e, 0x19, 0x56, 0xd2,
|
||||
0xcc, 0x8f, 0x0c, 0x28, 0x6f, 0x1e, 0xec, 0x62, 0x55, 0x84, 0x19, 0x8a, 0x66, 0x03, 0x40, 0xfc,
|
||||
0x65, 0x81, 0xd5, 0x21, 0x76, 0x35, 0xb7, 0x66, 0xdc, 0x2a, 0xb6, 0x90, 0xa2, 0x83, 0x87, 0x11,
|
||||
0x06, 0x27, 0xa8, 0x84, 0xd4, 0x53, 0xc7, 0xb3, 0x65, 0xb6, 0x13, 0x52, 0xdf, 0x76, 0x3c, 0x1b,
|
||||
0x4b, 0x0c, 0x7a, 0x00, 0xf9, 0x01, 0xa1, 0x47, 0x22, 0xfe, 0xa2, 0x20, 0xbe, 0x92, 0xcd, 0xbd,
|
||||
0xc7, 0x82, 0xa5, 0x55, 0xba, 0x18, 0xd6, 0xf3, 0xf2, 0x27, 0x0e, 0x85, 0x98, 0x7f, 0x35, 0x60,
|
||||
0x31, 0xe1, 0x95, 0x8c, 0xe0, 0x1d, 0x98, 0xef, 0x26, 0xea, 0x47, 0x79, 0xb8, 0xa2, 0x6c, 0x99,
|
||||
0x4f, 0xd6, 0x16, 0x4e, 0x51, 0x22, 0x02, 0x25, 0x7d, 0x49, 0xf5, 0x3d, 0x59, 0xcf, 0x1c, 0x7e,
|
||||
0x6d, 0x43, 0xac, 0x29, 0x01, 0x64, 0x38, 0x96, 0x6c, 0xfe, 0x3b, 0x4c, 0x85, 0xbe, 0x39, 0xe8,
|
||||
0x56, 0xe2, 0x76, 0x8a, 0xa4, 0x97, 0x5a, 0xf3, 0x13, 0x6e, 0xd6, 0x35, 0x25, 0x9d, 0xfb, 0x4c,
|
||||
0x94, 0xf4, 0xdd, 0xe2, 0xef, 0x3f, 0xa8, 0xcf, 0xbc, 0xff, 0x8f, 0xb5, 0x19, 0xf3, 0xd7, 0x39,
|
||||
0xa8, 0xb4, 0x89, 0x4b, 0x38, 0xd9, 0x0f, 0xb8, 0xf4, 0xe0, 0x3e, 0xa0, 0x2e, 0xb5, 0x3a, 0xe4,
|
||||
0x80, 0x50, 0xc7, 0xb7, 0x0f, 0x49, 0xc7, 0xf7, 0x6c, 0x26, 0x53, 0x34, 0xdb, 0xfa, 0xfc, 0xc5,
|
||||
0xb0, 0x8e, 0x76, 0xc6, 0xb0, 0xf8, 0x0a, 0x0e, 0xe4, 0x42, 0x25, 0xa0, 0xf2, 0xb7, 0xc3, 0x55,
|
||||
0x5b, 0x13, 0xe5, 0xf4, 0xb5, 0x6c, 0xbe, 0x1f, 0x24, 0x59, 0x5b, 0xcb, 0x17, 0xc3, 0x7a, 0x25,
|
||||
0x05, 0xc2, 0x69, 0xe1, 0xe8, 0x7b, 0xb0, 0xe4, 0xd3, 0xe0, 0xc4, 0xf2, 0xda, 0x24, 0x20, 0x9e,
|
||||
0x4d, 0x3c, 0xce, 0x64, 0x89, 0x17, 0x5b, 0x2b, 0xa2, 0x19, 0xed, 0x8f, 0xe0, 0xf0, 0x18, 0xb5,
|
||||
0xb9, 0x0b, 0xc5, 0x76, 0x9f, 0x5a, 0x42, 0x1c, 0xfa, 0x0e, 0x14, 0x6d, 0xf5, 0x5b, 0x79, 0xfe,
|
||||
0xaa, 0xee, 0xa6, 0x9a, 0xe6, 0x72, 0x58, 0xaf, 0x88, 0x31, 0xd3, 0xd0, 0x00, 0x1c, 0xb1, 0x98,
|
||||
0x4f, 0xa0, 0xb2, 0x7d, 0x16, 0xf8, 0x94, 0xeb, 0x98, 0x7e, 0x09, 0x0a, 0x44, 0x02, 0xa4, 0xb4,
|
||||
0x62, 0xdc, 0x02, 0x42, 0x32, 0xac, 0xb0, 0xe8, 0x35, 0xc8, 0x93, 0x33, 0xab, 0xc3, 0xd5, 0x5d,
|
||||
0xae, 0x28, 0xb2, 0xfc, 0xb6, 0x00, 0xe2, 0x10, 0x67, 0xee, 0x03, 0xec, 0x90, 0x48, 0xf4, 0x26,
|
||||
0x2c, 0xea, 0xba, 0x4d, 0x5f, 0xa7, 0x2f, 0x28, 0xe6, 0x45, 0x9c, 0x46, 0xe3, 0x51, 0x7a, 0xf3,
|
||||
0x09, 0x94, 0xe4, 0x95, 0x13, 0x3d, 0x40, 0x98, 0x20, 0x6f, 0x9c, 0x92, 0x12, 0x99, 0x20, 0x29,
|
||||
0x70, 0x88, 0x8b, 0x9a, 0x48, 0x6e, 0x52, 0x13, 0x49, 0x54, 0x98, 0x0b, 0x95, 0x90, 0x57, 0xf7,
|
||||
0xb5, 0x4c, 0x1a, 0x6e, 0x43, 0x51, 0x9b, 0xa9, 0xb4, 0x44, 0xf3, 0x4c, 0x0b, 0xc2, 0x11, 0x45,
|
||||
0x42, 0xdb, 0x09, 0xa4, 0xda, 0x47, 0x36, 0x65, 0x6f, 0xc0, 0x0d, 0x75, 0x81, 0x95, 0xae, 0x45,
|
||||
0x45, 0x76, 0x43, 0xc7, 0x4c, 0xe3, 0x13, 0x9a, 0x7e, 0x0e, 0xd5, 0x49, 0x43, 0xf0, 0x13, 0x34,
|
||||
0xb8, 0xec, 0xa6, 0x98, 0xbf, 0x33, 0x60, 0x29, 0x29, 0x29, 0x7b, 0xfa, 0xb2, 0x2b, 0xb9, 0x7e,
|
||||
0x5c, 0x24, 0x22, 0xf2, 0x47, 0x03, 0x56, 0x52, 0xae, 0x4d, 0x95, 0xf1, 0x29, 0x8c, 0x4a, 0x16,
|
||||
0xc7, 0xec, 0x14, 0xc5, 0xf1, 0x51, 0x0e, 0x2a, 0x0f, 0xac, 0x23, 0xe2, 0x1e, 0x12, 0x97, 0x74,
|
||||
0xb8, 0x4f, 0xd1, 0x7b, 0x50, 0xee, 0x59, 0xbc, 0x73, 0x22, 0xa1, 0x7a, 0xa0, 0xb7, 0xb3, 0xb5,
|
||||
0xa8, 0x94, 0xa4, 0xc6, 0x5e, 0x2c, 0x66, 0xdb, 0xe3, 0xf4, 0xbc, 0xf5, 0x39, 0x65, 0x52, 0x39,
|
||||
0x81, 0xc1, 0x49, 0x6d, 0x72, 0x0b, 0x93, 0xe7, 0xed, 0xb3, 0x40, 0xf4, 0xe8, 0xe9, 0x97, 0xbf,
|
||||
0x94, 0x09, 0x98, 0xfc, 0xb4, 0xef, 0x50, 0xd2, 0x23, 0x1e, 0x8f, 0xb7, 0xb0, 0xbd, 0x11, 0xf9,
|
||||
0x78, 0x4c, 0xe3, 0xea, 0x3d, 0x58, 0x1a, 0x35, 0x1e, 0x2d, 0xc1, 0xec, 0x29, 0x39, 0x0f, 0xf3,
|
||||
0x85, 0xc5, 0x4f, 0xb4, 0x02, 0xf9, 0x81, 0xe5, 0xf6, 0xd5, 0x6d, 0xc4, 0xe1, 0xe1, 0x6e, 0xee,
|
||||
0x8e, 0x61, 0xfe, 0xd9, 0x80, 0xea, 0x24, 0x43, 0xd0, 0x17, 0x13, 0x82, 0x5a, 0x65, 0x65, 0xd5,
|
||||
0xec, 0xdb, 0xe4, 0x3c, 0x94, 0xba, 0x0d, 0x45, 0x3f, 0x10, 0x7b, 0xb3, 0x4f, 0x55, 0xd6, 0xdf,
|
||||
0xd0, 0x99, 0xdc, 0x57, 0xf0, 0xcb, 0x61, 0xfd, 0x66, 0x4a, 0xbc, 0x46, 0xe0, 0x88, 0x15, 0x99,
|
||||
0x50, 0x90, 0xf6, 0x88, 0x9e, 0x2f, 0xa6, 0x33, 0x88, 0xde, 0xfa, 0x58, 0x42, 0xb0, 0xc2, 0x98,
|
||||
0xef, 0x41, 0x51, 0x2c, 0x1f, 0x7b, 0x84, 0x5b, 0xa2, 0x80, 0x18, 0x71, 0x8f, 0x1f, 0x38, 0xde,
|
||||
0xa9, 0x32, 0x2d, 0x2a, 0xa0, 0x43, 0x05, 0xc7, 0x11, 0xc5, 0x55, 0x2d, 0x36, 0x37, 0x65, 0x8b,
|
||||
0xfd, 0x4b, 0x0e, 0xca, 0x42, 0xbb, 0xee, 0xda, 0xdf, 0x82, 0x8a, 0x9b, 0xf4, 0x49, 0x59, 0x71,
|
||||
0x53, 0x09, 0x4c, 0x57, 0x29, 0x4e, 0xd3, 0x0a, 0xe6, 0x63, 0x87, 0xb8, 0x76, 0xc4, 0x9c, 0x4b,
|
||||
0x33, 0xdf, 0x4f, 0x22, 0x71, 0x9a, 0x56, 0xdc, 0xc5, 0xa7, 0x22, 0xdb, 0x6a, 0x3a, 0x46, 0x77,
|
||||
0xf1, 0xfb, 0x02, 0x88, 0x43, 0xdc, 0x55, 0x1e, 0xcf, 0x4d, 0xe7, 0x31, 0xba, 0x0b, 0x0b, 0x62,
|
||||
0x3c, 0xfa, 0x7d, 0xae, 0x57, 0x88, 0xbc, 0x1c, 0xa4, 0xe8, 0x62, 0x58, 0x5f, 0x78, 0x27, 0x85,
|
||||
0xc1, 0x23, 0x94, 0xe6, 0x2f, 0x00, 0x60, 0xff, 0xe8, 0x27, 0xa4, 0x13, 0x66, 0xeb, 0xfa, 0x45,
|
||||
0x58, 0xf4, 0x5b, 0xf5, 0xfe, 0x12, 0x50, 0x15, 0x90, 0xb8, 0xdf, 0x26, 0x70, 0x38, 0x45, 0x89,
|
||||
0x9a, 0x50, 0x8a, 0x96, 0x63, 0xd5, 0x4b, 0x96, 0x15, 0x5b, 0x29, 0xda, 0xa0, 0x71, 0x4c, 0x93,
|
||||
0x2a, 0x9d, 0xb9, 0x6b, 0x4b, 0xa7, 0x05, 0xb3, 0x7d, 0xc7, 0x96, 0xae, 0x97, 0x5a, 0x5f, 0xd5,
|
||||
0xe5, 0xff, 0x68, 0xb7, 0x7d, 0x39, 0xac, 0xbf, 0x3a, 0xe9, 0x01, 0xcb, 0xcf, 0x03, 0xc2, 0x1a,
|
||||
0x8f, 0x76, 0xdb, 0x58, 0x30, 0x5f, 0x95, 0x8c, 0xc2, 0x94, 0xc9, 0xd8, 0x00, 0x50, 0x5e, 0x0b,
|
||||
0xee, 0x1b, 0x61, 0x22, 0xf4, 0x43, 0x61, 0x27, 0xc2, 0xe0, 0x04, 0x15, 0x62, 0xb0, 0xdc, 0xa1,
|
||||
0x44, 0xfe, 0x16, 0xe9, 0x62, 0xdc, 0xea, 0x05, 0xd5, 0xa2, 0xdc, 0xe1, 0xbe, 0x9c, 0xad, 0x3b,
|
||||
0x09, 0xb6, 0xd6, 0x2b, 0x4a, 0xcd, 0xf2, 0xd6, 0xa8, 0x30, 0x3c, 0x2e, 0x1f, 0xf9, 0xb0, 0x6c,
|
||||
0x8b, 0x6d, 0x34, 0xa5, 0xb4, 0x34, 0xb5, 0xd2, 0x9b, 0x42, 0x61, 0x7b, 0x54, 0x10, 0x1e, 0x97,
|
||||
0x8d, 0x7e, 0x04, 0xab, 0x1a, 0x38, 0xbe, 0xd7, 0x56, 0x41, 0x46, 0xaa, 0x26, 0x36, 0xed, 0xf6,
|
||||
0x44, 0x2a, 0xfc, 0x31, 0x12, 0x90, 0x0d, 0x05, 0x37, 0x9c, 0x2d, 0x65, 0xd9, 0xd8, 0xbf, 0x9d,
|
||||
0xcd, 0x8b, 0xb8, 0xfa, 0x1b, 0xc9, 0x99, 0x12, 0xed, 0x8d, 0x6a, 0x9c, 0x28, 0xd9, 0xe8, 0x0c,
|
||||
0xca, 0x96, 0xe7, 0xf9, 0xdc, 0x0a, 0x37, 0xed, 0x79, 0xa9, 0x6a, 0x73, 0x6a, 0x55, 0x9b, 0xb1,
|
||||
0x8c, 0x91, 0x19, 0x96, 0xc0, 0xe0, 0xa4, 0x2a, 0xf4, 0x14, 0x16, 0xfd, 0xa7, 0x1e, 0xa1, 0x58,
|
||||
0x3c, 0xed, 0x89, 0x27, 0x9e, 0x65, 0x15, 0xa9, 0xfd, 0xeb, 0x19, 0xb5, 0xa7, 0x98, 0xe3, 0x92,
|
||||
0x4e, 0xc3, 0x19, 0x1e, 0xd5, 0x82, 0x1a, 0x00, 0xc7, 0x8e, 0x67, 0xb9, 0xce, 0xcf, 0x08, 0x65,
|
||||
0xd5, 0x05, 0xd9, 0xf6, 0x17, 0x44, 0x39, 0xdf, 0x8f, 0xa0, 0x38, 0x41, 0x81, 0xbe, 0x01, 0xe5,
|
||||
0x8e, 0xdb, 0x67, 0x9c, 0x50, 0xd9, 0x21, 0x16, 0xe5, 0x0d, 0x8a, 0xfc, 0xdb, 0x8a, 0x51, 0x38,
|
||||
0x49, 0xb7, 0xfa, 0x4d, 0x28, 0xff, 0x9f, 0x73, 0x51, 0xcc, 0xd5, 0xd1, 0x80, 0x4e, 0x35, 0x57,
|
||||
0xff, 0x6b, 0xc0, 0x42, 0x3a, 0x0c, 0xd1, 0x36, 0x66, 0x4c, 0x7c, 0xbc, 0xeb, 0x5e, 0x39, 0x3b,
|
||||
0xb1, 0x57, 0xaa, 0x96, 0x34, 0xf7, 0x49, 0x5a, 0xd2, 0x06, 0x80, 0x15, 0x38, 0xba, 0x1b, 0x85,
|
||||
0xdd, 0x2d, 0xea, 0x27, 0xf1, 0xc3, 0x19, 0x27, 0xa8, 0x44, 0xc2, 0x3a, 0xbe, 0xc7, 0xa9, 0xef,
|
||||
0xba, 0x84, 0xca, 0x0e, 0x56, 0x0c, 0x13, 0xb6, 0x15, 0x41, 0x71, 0x82, 0xc2, 0xdc, 0x87, 0xf4,
|
||||
0x8b, 0x0f, 0xdd, 0x0b, 0x0d, 0x0f, 0x7d, 0xbf, 0x3d, 0xb5, 0xd1, 0xe6, 0x6d, 0x28, 0x61, 0xdf,
|
||||
0xe7, 0x07, 0x16, 0x3f, 0x61, 0xa8, 0x0e, 0xf9, 0x40, 0xfc, 0x50, 0xcf, 0x79, 0xf9, 0xdd, 0x42,
|
||||
0x62, 0x70, 0x08, 0x37, 0x7f, 0x6b, 0xc0, 0x2b, 0x13, 0x5f, 0xd7, 0x22, 0x00, 0x9d, 0xe8, 0xa4,
|
||||
0x4c, 0x8a, 0x02, 0x10, 0xd3, 0xe1, 0x04, 0x95, 0x18, 0xdb, 0xa9, 0x27, 0xf9, 0xe8, 0xd8, 0x4e,
|
||||
0x69, 0xc3, 0x69, 0x5a, 0xf3, 0x3f, 0x39, 0x28, 0x1c, 0x72, 0x8b, 0xf7, 0x19, 0x7a, 0x02, 0x45,
|
||||
0x71, 0x7b, 0x6c, 0x8b, 0x5b, 0x52, 0x73, 0xe6, 0x2f, 0x50, 0x7a, 0xfd, 0x89, 0x27, 0x96, 0x86,
|
||||
0xe0, 0x48, 0xa2, 0x78, 0xaa, 0x32, 0xa9, 0x47, 0x99, 0x17, 0xb5, 0x9c, 0x50, 0x3b, 0x56, 0x58,
|
||||
0xb1, 0xae, 0xf7, 0x08, 0x63, 0x56, 0x57, 0xd7, 0x5a, 0xb4, 0xae, 0xef, 0x85, 0x60, 0xac, 0xf1,
|
||||
0xe8, 0x2d, 0x28, 0x50, 0x62, 0xb1, 0x68, 0x89, 0xa8, 0x69, 0x91, 0x58, 0x42, 0x2f, 0x87, 0xf5,
|
||||
0x79, 0x25, 0x5c, 0x9e, 0xb1, 0xa2, 0x46, 0xef, 0xc2, 0x0d, 0x9b, 0x70, 0xcb, 0x71, 0xc3, 0xdd,
|
||||
0x21, 0xf3, 0xb7, 0x83, 0x50, 0x58, 0x3b, 0x64, 0x6d, 0x95, 0x85, 0x4d, 0xea, 0x80, 0xb5, 0x40,
|
||||
0x71, 0x4f, 0x3a, 0xbe, 0x4d, 0x64, 0x1d, 0xe6, 0xe3, 0x7b, 0xb2, 0xe5, 0xdb, 0x04, 0x4b, 0x8c,
|
||||
0xf9, 0xcc, 0x80, 0x72, 0x28, 0x69, 0xcb, 0xea, 0x33, 0x82, 0xd6, 0x23, 0x2f, 0xc2, 0x74, 0xeb,
|
||||
0xc1, 0x36, 0xf7, 0xce, 0x79, 0x40, 0x2e, 0x87, 0xf5, 0x92, 0x24, 0x13, 0x87, 0xc8, 0x81, 0x44,
|
||||
0x8c, 0x72, 0xd7, 0xc4, 0xe8, 0x35, 0xc8, 0xcb, 0x3d, 0x4d, 0x05, 0x33, 0x5a, 0xcb, 0xe4, 0x2e,
|
||||
0x87, 0x43, 0x9c, 0xf9, 0x87, 0x1c, 0x54, 0x52, 0xce, 0x65, 0x58, 0x8d, 0xa2, 0xb7, 0x57, 0x2e,
|
||||
0xc3, 0x7b, 0x7e, 0xf2, 0x47, 0xc1, 0x1f, 0x40, 0xa1, 0x23, 0xfc, 0xd3, 0x5f, 0x65, 0xd7, 0xa7,
|
||||
0x49, 0x85, 0x8c, 0x4c, 0x5c, 0x49, 0xf2, 0xc8, 0xb0, 0x12, 0x88, 0x76, 0x60, 0x99, 0x12, 0x4e,
|
||||
0xcf, 0x37, 0x8f, 0x39, 0xa1, 0xc9, 0x65, 0x31, 0x1f, 0x2f, 0x0f, 0x78, 0x94, 0x00, 0x8f, 0xf3,
|
||||
0x98, 0x2e, 0xcc, 0x89, 0xc1, 0x2e, 0xc2, 0xce, 0x52, 0x9f, 0xad, 0xa2, 0xb0, 0x6b, 0x66, 0x8d,
|
||||
0x17, 0xd1, 0xf1, 0x2c, 0xcf, 0x0f, 0x8b, 0x3d, 0x1f, 0x47, 0xe7, 0xa1, 0x00, 0xe2, 0x10, 0x77,
|
||||
0x77, 0x45, 0x3c, 0x20, 0x7f, 0xf3, 0xbc, 0x3e, 0xf3, 0xec, 0x79, 0x7d, 0xe6, 0x83, 0xe7, 0xea,
|
||||
0x31, 0xf9, 0x43, 0x28, 0xc5, 0x6b, 0xc4, 0xa7, 0xac, 0xd2, 0xfc, 0x31, 0x14, 0x45, 0x25, 0xe9,
|
||||
0xf5, 0xf7, 0x9a, 0xa6, 0x9f, 0x6e, 0xc7, 0xb9, 0x2c, 0xed, 0xd8, 0xdc, 0x80, 0xf0, 0x3b, 0xad,
|
||||
0xe8, 0x84, 0x0e, 0x27, 0xbd, 0x54, 0x27, 0xdc, 0x15, 0x00, 0x1c, 0xc2, 0x13, 0xef, 0xe7, 0x5f,
|
||||
0x19, 0x00, 0xf2, 0x9d, 0xb0, 0x3d, 0x10, 0x6f, 0xbb, 0x35, 0x98, 0x13, 0x2d, 0x76, 0xd4, 0x30,
|
||||
0x79, 0x05, 0x24, 0x06, 0x3d, 0x82, 0x82, 0x2f, 0xd7, 0x0b, 0xf5, 0xf1, 0xef, 0xcd, 0x89, 0x55,
|
||||
0xa3, 0xfe, 0x69, 0xd3, 0xc0, 0xd6, 0xd3, 0xed, 0x33, 0x4e, 0x3c, 0x61, 0x63, 0x5c, 0x31, 0xe1,
|
||||
0x8e, 0x82, 0x95, 0xb0, 0xd6, 0xeb, 0x2f, 0x5e, 0xd6, 0x66, 0x3e, 0x7c, 0x59, 0x9b, 0xf9, 0xfb,
|
||||
0xcb, 0xda, 0xcc, 0xfb, 0x17, 0x35, 0xe3, 0xc5, 0x45, 0xcd, 0xf8, 0xf0, 0xa2, 0x66, 0xfc, 0xf3,
|
||||
0xa2, 0x66, 0x3c, 0xfb, 0x57, 0x6d, 0xe6, 0xdd, 0xdc, 0x60, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff,
|
||||
0xff, 0x0c, 0x01, 0x08, 0xec, 0xf6, 0x1a, 0x00, 0x00,
|
||||
// 2109 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x19, 0x4b, 0x6f, 0x23, 0x49,
|
||||
0x39, 0x6d, 0xc7, 0x1e, 0xfb, 0x73, 0x9c, 0x47, 0x31, 0x03, 0xde, 0x48, 0xd8, 0xd9, 0xde, 0x15,
|
||||
0x9a, 0x85, 0x59, 0x9b, 0x04, 0x58, 0x0d, 0x03, 0x0c, 0xc4, 0x71, 0x66, 0x14, 0xed, 0x64, 0x12,
|
||||
0x55, 0x76, 0x06, 0xb1, 0x8c, 0x10, 0x1d, 0x77, 0xc5, 0x69, 0xd2, 0xee, 0x6e, 0xaa, 0xca, 0x9e,
|
||||
0x84, 0x3d, 0xb0, 0xd2, 0x82, 0xe0, 0x80, 0xd0, 0x1c, 0x39, 0x20, 0xb4, 0x23, 0xb8, 0x71, 0xe3,
|
||||
0x4f, 0x30, 0xc7, 0x95, 0xb8, 0x70, 0x40, 0x16, 0x13, 0x0e, 0x1c, 0xb9, 0x47, 0x1c, 0x50, 0x55,
|
||||
0x57, 0xf5, 0xc3, 0x8e, 0x37, 0x6d, 0x76, 0x0f, 0x7b, 0x8a, 0xeb, 0x7b, 0xd7, 0x57, 0xdf, 0xb3,
|
||||
0x03, 0xbb, 0x27, 0xb7, 0x59, 0xd3, 0xf1, 0x5b, 0x27, 0x83, 0x43, 0x42, 0x3d, 0xc2, 0x09, 0x6b,
|
||||
0x0d, 0x89, 0x67, 0xfb, 0xb4, 0xa5, 0x10, 0x56, 0xe0, 0xf4, 0xad, 0xee, 0xb1, 0xe3, 0x11, 0x7a,
|
||||
0xd6, 0x0a, 0x4e, 0x7a, 0x02, 0xc0, 0x5a, 0x7d, 0xc2, 0xad, 0xd6, 0x70, 0xbd, 0xd5, 0x23, 0x1e,
|
||||
0xa1, 0x16, 0x27, 0x76, 0x33, 0xa0, 0x3e, 0xf7, 0xd1, 0xeb, 0x21, 0x57, 0x33, 0xc9, 0xd5, 0x0c,
|
||||
0x4e, 0x7a, 0x02, 0xc0, 0x9a, 0x82, 0xab, 0x39, 0x5c, 0x5f, 0x7d, 0xb3, 0xe7, 0xf0, 0xe3, 0xc1,
|
||||
0x61, 0xb3, 0xeb, 0xf7, 0x5b, 0x3d, 0xbf, 0xe7, 0xb7, 0x24, 0xf3, 0xe1, 0xe0, 0x48, 0x9e, 0xe4,
|
||||
0x41, 0xfe, 0x0a, 0x85, 0xae, 0x4e, 0x35, 0x85, 0x0e, 0x3c, 0xee, 0xf4, 0xc9, 0xb8, 0x15, 0xab,
|
||||
0x6f, 0x5d, 0xc5, 0xc0, 0xba, 0xc7, 0xa4, 0x6f, 0x4d, 0xf0, 0x6d, 0x4c, 0x3a, 0x43, 0xdd, 0xb8,
|
||||
0x45, 0x09, 0xf3, 0x07, 0xb4, 0x3b, 0xa9, 0x6b, 0xfd, 0x72, 0x9e, 0x01, 0x77, 0xdc, 0x96, 0xe3,
|
||||
0x71, 0xc6, 0xe9, 0x38, 0x8b, 0xf9, 0xd7, 0x3c, 0x94, 0x36, 0xf7, 0x77, 0xee, 0x53, 0x7f, 0x10,
|
||||
0xa0, 0x35, 0x98, 0xf7, 0xac, 0x3e, 0xa9, 0x19, 0x6b, 0xc6, 0xcd, 0x72, 0x7b, 0xe1, 0xc5, 0xa8,
|
||||
0x31, 0x77, 0x3e, 0x6a, 0xcc, 0x3f, 0xb4, 0xfa, 0x04, 0x4b, 0x0c, 0x72, 0xa1, 0x34, 0x24, 0x94,
|
||||
0x39, 0xbe, 0xc7, 0x6a, 0xb9, 0xb5, 0xfc, 0xcd, 0xca, 0xc6, 0xdd, 0x66, 0x16, 0x37, 0x37, 0xa5,
|
||||
0x82, 0xc7, 0x21, 0xeb, 0x3d, 0x9f, 0x76, 0x1c, 0xd6, 0xf5, 0x87, 0x84, 0x9e, 0xb5, 0x97, 0x95,
|
||||
0x96, 0x92, 0x42, 0x32, 0x1c, 0x69, 0x40, 0xbf, 0x30, 0x60, 0x39, 0xa0, 0xe4, 0x88, 0x50, 0x4a,
|
||||
0x6c, 0x85, 0xaf, 0xe5, 0xd7, 0x8c, 0x4f, 0x41, 0x6d, 0x4d, 0xa9, 0x5d, 0xde, 0x1f, 0x93, 0x8f,
|
||||
0x27, 0x34, 0xa2, 0x3f, 0x1a, 0xb0, 0xca, 0x08, 0x1d, 0x12, 0xba, 0x69, 0xdb, 0x94, 0x30, 0xd6,
|
||||
0x3e, 0xdb, 0x72, 0x1d, 0xe2, 0xf1, 0xad, 0x9d, 0x0e, 0x66, 0xb5, 0x79, 0xe9, 0x87, 0xef, 0x66,
|
||||
0x33, 0xe8, 0x60, 0x9a, 0x9c, 0xb6, 0xa9, 0x2c, 0x5a, 0x9d, 0x4a, 0xc2, 0xf0, 0xc7, 0x98, 0x61,
|
||||
0x1e, 0xc1, 0x82, 0x7e, 0xc8, 0x07, 0x0e, 0xe3, 0xe8, 0x31, 0x14, 0x7b, 0xe2, 0xc0, 0x6a, 0x86,
|
||||
0x34, 0xb0, 0x99, 0xcd, 0x40, 0x2d, 0xa3, 0xbd, 0xa8, 0xec, 0x29, 0xca, 0x23, 0xc3, 0x4a, 0x9a,
|
||||
0xf9, 0x41, 0x0e, 0x2a, 0x9b, 0xfb, 0x3b, 0x58, 0x05, 0x61, 0x86, 0xa0, 0xd9, 0x00, 0x10, 0x7f,
|
||||
0x59, 0x60, 0x75, 0x89, 0x5d, 0xcb, 0xad, 0x19, 0x37, 0x4b, 0x6d, 0xa4, 0xe8, 0xe0, 0x61, 0x84,
|
||||
0xc1, 0x09, 0x2a, 0x21, 0xf5, 0xc4, 0xf1, 0x6c, 0xf9, 0xda, 0x09, 0xa9, 0x6f, 0x3b, 0x9e, 0x8d,
|
||||
0x25, 0x06, 0x3d, 0x80, 0xc2, 0x90, 0xd0, 0x43, 0xe1, 0x7f, 0x11, 0x10, 0x5f, 0xc9, 0x76, 0xbd,
|
||||
0xc7, 0x82, 0xa5, 0x5d, 0x3e, 0x1f, 0x35, 0x0a, 0xf2, 0x27, 0x0e, 0x85, 0xa0, 0x26, 0x00, 0x3b,
|
||||
0xf6, 0x29, 0x97, 0xe6, 0xd4, 0x0a, 0x6b, 0xf9, 0x9b, 0xe5, 0xf6, 0xa2, 0xb0, 0xef, 0x20, 0x82,
|
||||
0xe2, 0x04, 0x85, 0xf9, 0x17, 0x03, 0x96, 0x12, 0x5e, 0x90, 0x1e, 0xbf, 0x0d, 0x0b, 0xbd, 0x44,
|
||||
0xbc, 0x29, 0x8f, 0x5c, 0x57, 0xb6, 0x2f, 0x24, 0x63, 0x11, 0xa7, 0x28, 0x11, 0x81, 0xb2, 0x4e,
|
||||
0x6a, 0x9d, 0x57, 0xeb, 0x99, 0x9f, 0x4b, 0xdb, 0x10, 0x6b, 0x4a, 0x00, 0x19, 0x8e, 0x25, 0x9b,
|
||||
0xff, 0x36, 0xe4, 0xd3, 0xe9, 0x4c, 0x43, 0x37, 0x13, 0xd9, 0x6c, 0xc8, 0x2b, 0x2f, 0x4c, 0xc9,
|
||||
0xc4, 0x2b, 0x52, 0x20, 0xf7, 0x99, 0x48, 0x81, 0x3b, 0xa5, 0xdf, 0x7d, 0xd8, 0x98, 0x7b, 0xff,
|
||||
0x1f, 0x6b, 0x73, 0xe6, 0xaf, 0x72, 0x50, 0xed, 0x10, 0x97, 0x70, 0xb2, 0x17, 0x70, 0x79, 0x83,
|
||||
0x7b, 0x80, 0x7a, 0xd4, 0xea, 0x92, 0x7d, 0x42, 0x1d, 0xdf, 0x3e, 0x20, 0x5d, 0xdf, 0xb3, 0x99,
|
||||
0x7c, 0xa2, 0x7c, 0xfb, 0xf3, 0xe7, 0xa3, 0x06, 0xba, 0x3f, 0x81, 0xc5, 0x97, 0x70, 0x20, 0x17,
|
||||
0xaa, 0x01, 0x95, 0xbf, 0x1d, 0xae, 0xca, 0xa0, 0x08, 0xbf, 0xaf, 0x65, 0xbb, 0xfb, 0x7e, 0x92,
|
||||
0xb5, 0xbd, 0x72, 0x3e, 0x6a, 0x54, 0x53, 0x20, 0x9c, 0x16, 0x8e, 0xbe, 0x07, 0xcb, 0x3e, 0x0d,
|
||||
0x8e, 0x2d, 0xaf, 0x43, 0x02, 0xe2, 0xd9, 0xc4, 0xe3, 0x4c, 0xa6, 0x44, 0xa9, 0x7d, 0x5d, 0x14,
|
||||
0xaf, 0xbd, 0x31, 0x1c, 0x9e, 0xa0, 0x36, 0x77, 0xa0, 0xd4, 0x19, 0x50, 0x4b, 0x88, 0x43, 0xdf,
|
||||
0x81, 0x92, 0xad, 0x7e, 0xab, 0x9b, 0xbf, 0xaa, 0xab, 0xaf, 0xa6, 0xb9, 0x18, 0x35, 0xaa, 0xa2,
|
||||
0x2d, 0x35, 0x35, 0x00, 0x47, 0x2c, 0xe6, 0x13, 0xa8, 0x6e, 0x9f, 0x06, 0x3e, 0xe5, 0xda, 0xa7,
|
||||
0x5f, 0x82, 0x22, 0x91, 0x00, 0x29, 0xad, 0x14, 0x97, 0x8c, 0x90, 0x0c, 0x2b, 0x2c, 0x7a, 0x0d,
|
||||
0x0a, 0xe4, 0xd4, 0xea, 0x72, 0x95, 0xfb, 0x55, 0x45, 0x56, 0xd8, 0x16, 0x40, 0x1c, 0xe2, 0xcc,
|
||||
0x3d, 0x80, 0xfb, 0x24, 0x12, 0xbd, 0x09, 0x4b, 0x3a, 0x6e, 0xd3, 0xe9, 0xf4, 0x05, 0xc5, 0xbc,
|
||||
0x84, 0xd3, 0x68, 0x3c, 0x4e, 0x6f, 0x3e, 0x81, 0xb2, 0x4c, 0x39, 0x51, 0x33, 0x84, 0x09, 0x32,
|
||||
0xe3, 0x94, 0x94, 0xc8, 0x04, 0x49, 0x81, 0x43, 0x5c, 0x54, 0x74, 0x72, 0xd3, 0x8a, 0x4e, 0x22,
|
||||
0xc2, 0x5c, 0xa8, 0x86, 0xbc, 0xba, 0x0e, 0x66, 0xd2, 0x70, 0x0b, 0x4a, 0xda, 0x4c, 0xa5, 0x25,
|
||||
0xea, 0x7f, 0x5a, 0x10, 0x8e, 0x28, 0x12, 0xda, 0x8e, 0x21, 0x55, 0x3e, 0xb2, 0x29, 0x7b, 0x03,
|
||||
0xae, 0xa9, 0x04, 0x56, 0xba, 0x96, 0x14, 0xd9, 0x35, 0xed, 0x33, 0x8d, 0x4f, 0x68, 0xfa, 0x39,
|
||||
0xd4, 0xa6, 0x35, 0xcd, 0x4f, 0x50, 0xe0, 0xb2, 0x9b, 0x62, 0xfe, 0xd6, 0x80, 0xe5, 0xa4, 0xa4,
|
||||
0xec, 0xcf, 0x97, 0x5d, 0xc9, 0xd5, 0xed, 0x25, 0xe1, 0x91, 0x3f, 0x18, 0x70, 0x3d, 0x75, 0xb5,
|
||||
0x99, 0x5e, 0x7c, 0x06, 0xa3, 0x92, 0xc1, 0x91, 0x9f, 0x21, 0x38, 0xfe, 0x96, 0x83, 0xea, 0x03,
|
||||
0xeb, 0x90, 0xb8, 0x07, 0xc4, 0x25, 0x5d, 0xee, 0x53, 0xf4, 0x1e, 0x54, 0xfa, 0x16, 0xef, 0x1e,
|
||||
0x4b, 0xa8, 0x1e, 0x00, 0x3a, 0xd9, 0x4a, 0x54, 0x4a, 0x52, 0x73, 0x37, 0x16, 0xb3, 0xed, 0x71,
|
||||
0x7a, 0xd6, 0xfe, 0x9c, 0x32, 0xa9, 0x92, 0xc0, 0xe0, 0xa4, 0x36, 0x39, 0xb5, 0xc9, 0xf3, 0xf6,
|
||||
0x69, 0x20, 0x6a, 0xf4, 0xec, 0xc3, 0x62, 0xca, 0x04, 0x4c, 0x7e, 0x3a, 0x70, 0x28, 0xe9, 0x13,
|
||||
0x8f, 0xc7, 0x53, 0xdb, 0xee, 0x98, 0x7c, 0x3c, 0xa1, 0x71, 0xf5, 0x2e, 0x2c, 0x8f, 0x1b, 0x8f,
|
||||
0x96, 0x21, 0x7f, 0x42, 0xce, 0xc2, 0xf7, 0xc2, 0xe2, 0x27, 0xba, 0x0e, 0x85, 0xa1, 0xe5, 0x0e,
|
||||
0x54, 0x36, 0xe2, 0xf0, 0x70, 0x27, 0x77, 0xdb, 0x30, 0xff, 0x64, 0x40, 0x6d, 0x9a, 0x21, 0xe8,
|
||||
0x8b, 0x09, 0x41, 0xed, 0x8a, 0xb2, 0x2a, 0xff, 0x36, 0x39, 0x0b, 0xa5, 0x6e, 0x43, 0xc9, 0x0f,
|
||||
0xc4, 0x9c, 0xed, 0x53, 0xf5, 0xea, 0x6f, 0xe8, 0x97, 0xdc, 0x53, 0xf0, 0x8b, 0x51, 0xe3, 0x46,
|
||||
0x4a, 0xbc, 0x46, 0xe0, 0x88, 0x15, 0x99, 0x50, 0x94, 0xf6, 0x88, 0x9a, 0x2f, 0xba, 0x33, 0x88,
|
||||
0xda, 0xfa, 0x58, 0x42, 0xb0, 0xc2, 0x98, 0xef, 0x41, 0x49, 0x0c, 0x1f, 0xbb, 0x84, 0x5b, 0x22,
|
||||
0x80, 0x18, 0x71, 0x8f, 0x1e, 0x38, 0xde, 0x89, 0x32, 0x2d, 0x0a, 0xa0, 0x03, 0x05, 0xc7, 0x11,
|
||||
0xc5, 0x65, 0x25, 0x36, 0x37, 0x63, 0x89, 0xfd, 0x73, 0x0e, 0x2a, 0x42, 0xbb, 0xae, 0xda, 0xdf,
|
||||
0x82, 0xaa, 0x9b, 0xbc, 0x93, 0xb2, 0xe2, 0x86, 0x12, 0x98, 0x8e, 0x52, 0x9c, 0xa6, 0x15, 0xcc,
|
||||
0x47, 0x0e, 0x71, 0xed, 0x88, 0x39, 0x97, 0x66, 0xbe, 0x97, 0x44, 0xe2, 0x34, 0xad, 0xc8, 0xc5,
|
||||
0xa7, 0xe2, 0xb5, 0x55, 0x77, 0x8c, 0x72, 0xf1, 0xfb, 0x02, 0x88, 0x43, 0xdc, 0x65, 0x37, 0x9e,
|
||||
0x9f, 0xed, 0xc6, 0xe8, 0x0e, 0x2c, 0x8a, 0xf6, 0xe8, 0x0f, 0xb8, 0x1e, 0x21, 0x0a, 0xb2, 0x91,
|
||||
0xa2, 0xf3, 0x51, 0x63, 0xf1, 0x9d, 0x14, 0x06, 0x8f, 0x51, 0x9a, 0x1f, 0x00, 0xc0, 0xde, 0xe1,
|
||||
0x4f, 0x48, 0x37, 0x7c, 0xad, 0xab, 0x07, 0x67, 0x51, 0x6f, 0xd5, 0xbe, 0x26, 0xa0, 0xca, 0x21,
|
||||
0x71, 0xbd, 0x4d, 0xe0, 0x70, 0x8a, 0x12, 0xb5, 0xa0, 0x1c, 0x0d, 0xd3, 0xaa, 0x96, 0xac, 0x28,
|
||||
0xb6, 0x72, 0x34, 0x71, 0xe3, 0x98, 0x26, 0x15, 0x3a, 0xf3, 0x57, 0x86, 0x4e, 0x1b, 0xf2, 0x03,
|
||||
0xc7, 0x96, 0x57, 0x2f, 0xb7, 0xbf, 0xaa, 0xc3, 0xff, 0xd1, 0x4e, 0xe7, 0x62, 0xd4, 0x78, 0x75,
|
||||
0xda, 0xc2, 0xcb, 0xcf, 0x02, 0xc2, 0x9a, 0x8f, 0x76, 0x3a, 0x58, 0x30, 0x5f, 0xf6, 0x18, 0xc5,
|
||||
0x19, 0x1f, 0x63, 0x03, 0x40, 0xdd, 0x5a, 0x70, 0x5f, 0x0b, 0x1f, 0x42, 0x2f, 0x16, 0xf7, 0x23,
|
||||
0x0c, 0x4e, 0x50, 0x21, 0x06, 0x2b, 0x5d, 0x4a, 0xe4, 0x6f, 0xf1, 0x5c, 0x8c, 0x5b, 0xfd, 0xa0,
|
||||
0x56, 0x92, 0x33, 0xdc, 0x97, 0xb3, 0x55, 0x27, 0xc1, 0xd6, 0x7e, 0x45, 0xa9, 0x59, 0xd9, 0x1a,
|
||||
0x17, 0x86, 0x27, 0xe5, 0x23, 0x1f, 0x56, 0x6c, 0x31, 0x8d, 0xa6, 0x94, 0x96, 0x67, 0x56, 0x7a,
|
||||
0x43, 0x28, 0xec, 0x8c, 0x0b, 0xc2, 0x93, 0xb2, 0xd1, 0x8f, 0x60, 0x55, 0x03, 0x27, 0xe7, 0xda,
|
||||
0x1a, 0x48, 0x4f, 0xd5, 0xc5, 0xa4, 0xdd, 0x99, 0x4a, 0x85, 0x3f, 0x46, 0x02, 0xb2, 0xa1, 0xe8,
|
||||
0x86, 0xbd, 0xa5, 0x22, 0x0b, 0xfb, 0xb7, 0xb3, 0xdd, 0x22, 0x8e, 0xfe, 0x66, 0xb2, 0xa7, 0x44,
|
||||
0x73, 0xa3, 0x6a, 0x27, 0x4a, 0x36, 0x3a, 0x85, 0x8a, 0xe5, 0x79, 0x3e, 0xb7, 0xc2, 0x49, 0x7b,
|
||||
0x41, 0xaa, 0xda, 0x9c, 0x59, 0xd5, 0x66, 0x2c, 0x63, 0xac, 0x87, 0x25, 0x30, 0x38, 0xa9, 0x0a,
|
||||
0x3d, 0x85, 0x25, 0xff, 0xa9, 0x47, 0x28, 0x26, 0x47, 0x84, 0x12, 0x4f, 0xac, 0x65, 0x55, 0xa9,
|
||||
0xfd, 0xeb, 0x19, 0xb5, 0xa7, 0x98, 0xe3, 0x90, 0x4e, 0xc3, 0x19, 0x1e, 0xd7, 0x22, 0xf6, 0xd0,
|
||||
0x23, 0xc7, 0xb3, 0x5c, 0xe7, 0x67, 0x84, 0xb2, 0xda, 0x62, 0xbc, 0x87, 0xde, 0x8b, 0xa0, 0x38,
|
||||
0x41, 0x81, 0xbe, 0x01, 0x95, 0xae, 0x3b, 0x60, 0x9c, 0x50, 0x59, 0x21, 0x96, 0x64, 0x06, 0x45,
|
||||
0xf7, 0xdb, 0x8a, 0x51, 0x38, 0x49, 0xb7, 0xfa, 0x4d, 0xa8, 0xfc, 0x9f, 0x7d, 0x51, 0xf4, 0xd5,
|
||||
0x71, 0x87, 0xce, 0xd4, 0x57, 0xff, 0x6b, 0xc0, 0x62, 0xda, 0x0d, 0xd1, 0x34, 0x66, 0x4c, 0x5d,
|
||||
0xf6, 0x75, 0xad, 0xcc, 0x4f, 0xad, 0x95, 0xaa, 0x24, 0xcd, 0x7f, 0x92, 0x92, 0xb4, 0x01, 0x60,
|
||||
0x05, 0x8e, 0xae, 0x46, 0x61, 0x75, 0x8b, 0xea, 0x49, 0xbc, 0x38, 0xe3, 0x04, 0x95, 0x78, 0xb0,
|
||||
0xae, 0xef, 0x71, 0xea, 0xbb, 0x2e, 0xa1, 0xb2, 0x82, 0x95, 0xc2, 0x07, 0xdb, 0x8a, 0xa0, 0x38,
|
||||
0x41, 0x61, 0xee, 0x41, 0x7a, 0xe3, 0x43, 0x77, 0x43, 0xc3, 0xc3, 0xbb, 0xdf, 0x9a, 0xd9, 0x68,
|
||||
0xf3, 0x16, 0x94, 0xb1, 0xef, 0xf3, 0x7d, 0x8b, 0x1f, 0x33, 0xd4, 0x80, 0x42, 0x20, 0x7e, 0xa8,
|
||||
0x75, 0x5e, 0x7e, 0xe7, 0x90, 0x18, 0x1c, 0xc2, 0xcd, 0xdf, 0x18, 0xf0, 0xca, 0xd4, 0xed, 0x5a,
|
||||
0x38, 0xa0, 0x1b, 0x9d, 0x94, 0x49, 0x91, 0x03, 0x62, 0x3a, 0x9c, 0xa0, 0x12, 0x6d, 0x3b, 0xb5,
|
||||
0x92, 0x8f, 0xb7, 0xed, 0x94, 0x36, 0x9c, 0xa6, 0x35, 0xff, 0x93, 0x83, 0xe2, 0x01, 0xb7, 0xf8,
|
||||
0x80, 0xa1, 0x27, 0x50, 0x12, 0xd9, 0x63, 0x5b, 0xdc, 0x92, 0x9a, 0x33, 0x7f, 0xb1, 0xd2, 0xe3,
|
||||
0x4f, 0xdc, 0xb1, 0x34, 0x04, 0x47, 0x12, 0xc5, 0xaa, 0xca, 0xa4, 0x1e, 0x65, 0x5e, 0x54, 0x72,
|
||||
0x42, 0xed, 0x58, 0x61, 0xc5, 0xb8, 0xde, 0x27, 0x8c, 0x59, 0x3d, 0x1d, 0x6b, 0xd1, 0xb8, 0xbe,
|
||||
0x1b, 0x82, 0xb1, 0xc6, 0xa3, 0xb7, 0xa0, 0x48, 0x89, 0xc5, 0xa2, 0x21, 0xa2, 0xae, 0x45, 0x62,
|
||||
0x09, 0xbd, 0x18, 0x35, 0x16, 0x94, 0x70, 0x79, 0xc6, 0x8a, 0x1a, 0xbd, 0x0b, 0xd7, 0x6c, 0xc2,
|
||||
0x2d, 0xc7, 0x0d, 0x67, 0x87, 0xcc, 0xdf, 0x0e, 0x42, 0x61, 0x9d, 0x90, 0xb5, 0x5d, 0x11, 0x36,
|
||||
0xa9, 0x03, 0xd6, 0x02, 0x45, 0x9e, 0x74, 0x7d, 0x9b, 0xc8, 0x38, 0x2c, 0xc4, 0x79, 0xb2, 0xe5,
|
||||
0xdb, 0x04, 0x4b, 0x8c, 0xf9, 0xcc, 0x80, 0x4a, 0x28, 0x69, 0xcb, 0x1a, 0x30, 0x82, 0xd6, 0xa3,
|
||||
0x5b, 0x84, 0xcf, 0xad, 0x1b, 0xdb, 0xfc, 0x3b, 0x67, 0x01, 0xb9, 0x18, 0x35, 0xca, 0x92, 0x4c,
|
||||
0x1c, 0xa2, 0x0b, 0x24, 0x7c, 0x94, 0xbb, 0xc2, 0x47, 0xaf, 0x41, 0x41, 0xce, 0x69, 0xca, 0x99,
|
||||
0xd1, 0x58, 0x26, 0x67, 0x39, 0x1c, 0xe2, 0xcc, 0xdf, 0xe7, 0xa0, 0x9a, 0xba, 0x5c, 0x86, 0xd1,
|
||||
0x28, 0xda, 0xbd, 0x72, 0x19, 0xf6, 0xf9, 0xe9, 0x1f, 0x11, 0x7f, 0x00, 0xc5, 0xae, 0xb8, 0x9f,
|
||||
0xfe, 0x8a, 0xbb, 0x3e, 0xcb, 0x53, 0x48, 0xcf, 0xc4, 0x91, 0x24, 0x8f, 0x0c, 0x2b, 0x81, 0xe8,
|
||||
0x3e, 0xac, 0x50, 0xc2, 0xe9, 0xd9, 0xe6, 0x11, 0x27, 0x34, 0x39, 0x2c, 0x16, 0xe2, 0xe1, 0x01,
|
||||
0x8f, 0x13, 0xe0, 0x49, 0x1e, 0xd3, 0x85, 0x79, 0xd1, 0xd8, 0x85, 0xdb, 0x59, 0xea, 0xb3, 0x55,
|
||||
0xe4, 0x76, 0xcd, 0xac, 0xf1, 0xc2, 0x3b, 0x9e, 0xe5, 0xf9, 0x61, 0xb0, 0x17, 0x62, 0xef, 0x3c,
|
||||
0x14, 0x40, 0x1c, 0xe2, 0xee, 0x5c, 0x17, 0x0b, 0xe4, 0xaf, 0x9f, 0x37, 0xe6, 0x9e, 0x3d, 0x6f,
|
||||
0xcc, 0x7d, 0xf8, 0x5c, 0x2d, 0x93, 0x3f, 0x84, 0x72, 0x3c, 0x46, 0x7c, 0xca, 0x2a, 0xcd, 0x1f,
|
||||
0x43, 0x49, 0x44, 0x92, 0x1e, 0x7f, 0xaf, 0x28, 0xfa, 0xe9, 0x72, 0x9c, 0xcb, 0x52, 0x8e, 0xcd,
|
||||
0x0d, 0x08, 0xbf, 0xeb, 0x8a, 0x4a, 0xe8, 0x70, 0xd2, 0x4f, 0x55, 0xc2, 0x1d, 0x01, 0xc0, 0x21,
|
||||
0x3c, 0xb1, 0x3f, 0xff, 0xd2, 0x00, 0x90, 0x7b, 0xc2, 0xf6, 0x50, 0xec, 0x76, 0x6b, 0x30, 0x2f,
|
||||
0x4a, 0xec, 0xb8, 0x61, 0x32, 0x05, 0x24, 0x06, 0x3d, 0x82, 0xa2, 0x2f, 0xc7, 0x0b, 0xf5, 0xf1,
|
||||
0xef, 0xcd, 0xa9, 0x51, 0xa3, 0xfe, 0xc9, 0xd3, 0xc4, 0xd6, 0xd3, 0xed, 0x53, 0x4e, 0x3c, 0x61,
|
||||
0x63, 0x1c, 0x31, 0xe1, 0x8c, 0x82, 0x95, 0xb0, 0xf6, 0xeb, 0x2f, 0x5e, 0xd6, 0xe7, 0x3e, 0x7a,
|
||||
0x59, 0x9f, 0xfb, 0xfb, 0xcb, 0xfa, 0xdc, 0xfb, 0xe7, 0x75, 0xe3, 0xc5, 0x79, 0xdd, 0xf8, 0xe8,
|
||||
0xbc, 0x6e, 0xfc, 0xf3, 0xbc, 0x6e, 0x3c, 0xfb, 0x57, 0x7d, 0xee, 0xdd, 0xdc, 0x70, 0xfd, 0x7f,
|
||||
0x01, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xe1, 0xb9, 0xfd, 0x26, 0x1b, 0x00, 0x00,
|
||||
}
|
||||
|
@@ -74,6 +74,9 @@ message APIResource {
|
||||
// verbs is a list of supported kube verbs (this includes get, list, watch, create,
|
||||
// update, patch, delete, deletecollection, and proxy)
|
||||
optional Verbs verbs = 4;
|
||||
|
||||
// shortNames is a list of suggested short names of the resource.
|
||||
repeated string shortNames = 5;
|
||||
}
|
||||
|
||||
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
||||
|
@@ -42,6 +42,7 @@ func AddToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion)
|
||||
schema.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal}.WithKind(WatchEventKind),
|
||||
&InternalEvent{},
|
||||
)
|
||||
// Supports legacy code paths, most callers should use metav1.ParameterCodec for now
|
||||
scheme.AddKnownTypes(groupVersion,
|
||||
&ListOptions{},
|
||||
&ExportOptions{},
|
||||
@@ -65,5 +66,8 @@ var ParameterCodec = runtime.NewParameterCodec(scheme)
|
||||
func init() {
|
||||
scheme.AddUnversionedTypes(SchemeGroupVersion,
|
||||
&ListOptions{},
|
||||
&ExportOptions{},
|
||||
&GetOptions{},
|
||||
&DeleteOptions{},
|
||||
)
|
||||
}
|
||||
|
@@ -648,6 +648,8 @@ type APIResource struct {
|
||||
// verbs is a list of supported kube verbs (this includes get, list, watch, create,
|
||||
// update, patch, delete, deletecollection, and proxy)
|
||||
Verbs Verbs `json:"verbs" protobuf:"bytes,4,opt,name=verbs"`
|
||||
// shortNames is a list of suggested short names of the resource.
|
||||
ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,5,rep,name=shortNames"`
|
||||
}
|
||||
|
||||
// Verbs masks the value so protobuf can generate
|
||||
|
@@ -54,6 +54,7 @@ var map_APIResource = map[string]string{
|
||||
"namespaced": "namespaced indicates if a resource is namespaced or not.",
|
||||
"kind": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
|
||||
"verbs": "verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy)",
|
||||
"shortNames": "shortNames is a list of suggested short names of the resource.",
|
||||
}
|
||||
|
||||
func (APIResource) SwaggerDoc() map[string]string {
|
||||
|
@@ -115,6 +115,11 @@ func DeepCopy_v1_APIResource(in interface{}, out interface{}, c *conversion.Clon
|
||||
*out = make(Verbs, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ShortNames != nil {
|
||||
in, out := &in.ShortNames, &out.ShortNames
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
forkedjson "k8s.io/client-go/third_party/forked/golang/json"
|
||||
forkedjson "k8s.io/apimachinery/third_party/forked/golang/json"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ghodss/yaml"
|
@@ -69,11 +69,10 @@ func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
||||
}
|
||||
|
||||
if len(bytes) != 0 {
|
||||
data, err := yaml.YAMLToJSON(bytes)
|
||||
err := yaml.Unmarshal(bytes, into)
|
||||
if err != nil {
|
||||
return err
|
||||
return YAMLSyntaxError{err}
|
||||
}
|
||||
return json.Unmarshal(data, into)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -184,6 +183,23 @@ type YAMLOrJSONDecoder struct {
|
||||
rawData []byte
|
||||
}
|
||||
|
||||
type JSONSyntaxError struct {
|
||||
Line int
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e JSONSyntaxError) Error() string {
|
||||
return fmt.Sprintf("json: line %d: %s", e.Line, e.Err.Error())
|
||||
}
|
||||
|
||||
type YAMLSyntaxError struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e YAMLSyntaxError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
// NewYAMLOrJSONDecoder returns a decoder that will process YAML documents
|
||||
// or JSON documents from the given reader as a stream. bufferSize determines
|
||||
// how far into the stream the decoder will look to figure out whether this
|
||||
@@ -226,7 +242,10 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
|
||||
|
||||
start := strings.LastIndex(js[:syntax.Offset], "\n") + 1
|
||||
line := strings.Count(js[:start], "\n")
|
||||
return fmt.Errorf("json: line %d: %s", line, syntax.Error())
|
||||
return JSONSyntaxError{
|
||||
Line: line,
|
||||
Err: fmt.Errorf(syntax.Error()),
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
@@ -30,9 +30,9 @@ import (
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/third_party/forked/golang/netutil"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
"k8s.io/client-go/pkg/util/httpstream"
|
||||
"k8s.io/client-go/third_party/forked/golang/netutil"
|
||||
)
|
||||
|
||||
// SpdyRoundTripper knows how to upgrade an HTTP request to one that supports
|
||||
|
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 util
|
||||
|
||||
// A simple trie implementation with Add an HasPrefix methods only.
|
||||
type Trie struct {
|
||||
children map[byte]*Trie
|
||||
wordTail bool
|
||||
word string
|
||||
}
|
||||
|
||||
// CreateTrie creates a Trie and add all strings in the provided list to it.
|
||||
func CreateTrie(list []string) Trie {
|
||||
ret := Trie{
|
||||
children: make(map[byte]*Trie),
|
||||
wordTail: false,
|
||||
}
|
||||
for _, v := range list {
|
||||
ret.Add(v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Add adds a word to this trie
|
||||
func (t *Trie) Add(v string) {
|
||||
root := t
|
||||
for _, b := range []byte(v) {
|
||||
child, exists := root.children[b]
|
||||
if !exists {
|
||||
child = &Trie{
|
||||
children: make(map[byte]*Trie),
|
||||
wordTail: false,
|
||||
}
|
||||
root.children[b] = child
|
||||
}
|
||||
root = child
|
||||
}
|
||||
root.wordTail = true
|
||||
root.word = v
|
||||
}
|
||||
|
||||
// HasPrefix returns true of v has any of the prefixes stored in this trie.
|
||||
func (t *Trie) HasPrefix(v string) bool {
|
||||
_, has := t.GetPrefix(v)
|
||||
return has
|
||||
}
|
||||
|
||||
// GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise.
|
||||
func (t *Trie) GetPrefix(v string) (string, bool) {
|
||||
root := t
|
||||
if root.wordTail {
|
||||
return root.word, true
|
||||
}
|
||||
for _, b := range []byte(v) {
|
||||
child, exists := root.children[b]
|
||||
if !exists {
|
||||
return "", false
|
||||
}
|
||||
if child.wordTail {
|
||||
return child.word, true
|
||||
}
|
||||
root = child
|
||||
}
|
||||
return "", false
|
||||
}
|
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/juju/ratelimit"
|
||||
)
|
||||
|
||||
type RateLimiter interface {
|
||||
// When gets an item and gets to decide how long that item should wait
|
||||
When(item interface{}) time.Duration
|
||||
// Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing
|
||||
// or for success, we'll stop tracking it
|
||||
Forget(item interface{})
|
||||
// NumRequeues returns back how many failures the item has had
|
||||
NumRequeues(item interface{}) int
|
||||
}
|
||||
|
||||
// DefaultControllerRateLimiter is a no-arg constructor for a default rate limiter for a workqueue. It has
|
||||
// both overall and per-item rate limitting. The overall is a token bucket and the per-item is exponential
|
||||
func DefaultControllerRateLimiter() RateLimiter {
|
||||
return NewMaxOfRateLimiter(
|
||||
NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
|
||||
// 10 qps, 100 bucket size. This is only for retry speed and its only the overall factor (not per item)
|
||||
&BucketRateLimiter{Bucket: ratelimit.NewBucketWithRate(float64(10), int64(100))},
|
||||
)
|
||||
}
|
||||
|
||||
// BucketRateLimiter adapts a standard bucket to the workqueue ratelimiter API
|
||||
type BucketRateLimiter struct {
|
||||
*ratelimit.Bucket
|
||||
}
|
||||
|
||||
var _ RateLimiter = &BucketRateLimiter{}
|
||||
|
||||
func (r *BucketRateLimiter) When(item interface{}) time.Duration {
|
||||
return r.Bucket.Take(1)
|
||||
}
|
||||
|
||||
func (r *BucketRateLimiter) NumRequeues(item interface{}) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (r *BucketRateLimiter) Forget(item interface{}) {
|
||||
}
|
||||
|
||||
// ItemExponentialFailureRateLimiter does a simple baseDelay*10^<num-failures> limit
|
||||
// dealing with max failures and expiration are up to the caller
|
||||
type ItemExponentialFailureRateLimiter struct {
|
||||
failuresLock sync.Mutex
|
||||
failures map[interface{}]int
|
||||
|
||||
baseDelay time.Duration
|
||||
maxDelay time.Duration
|
||||
}
|
||||
|
||||
var _ RateLimiter = &ItemExponentialFailureRateLimiter{}
|
||||
|
||||
func NewItemExponentialFailureRateLimiter(baseDelay time.Duration, maxDelay time.Duration) RateLimiter {
|
||||
return &ItemExponentialFailureRateLimiter{
|
||||
failures: map[interface{}]int{},
|
||||
baseDelay: baseDelay,
|
||||
maxDelay: maxDelay,
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultItemBasedRateLimiter() RateLimiter {
|
||||
return NewItemExponentialFailureRateLimiter(time.Millisecond, 1000*time.Second)
|
||||
}
|
||||
|
||||
func (r *ItemExponentialFailureRateLimiter) When(item interface{}) time.Duration {
|
||||
r.failuresLock.Lock()
|
||||
defer r.failuresLock.Unlock()
|
||||
|
||||
exp := r.failures[item]
|
||||
r.failures[item] = r.failures[item] + 1
|
||||
|
||||
// The backoff is capped such that 'calculated' value never overflows.
|
||||
backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow(2, float64(exp))
|
||||
if backoff > math.MaxInt64 {
|
||||
return r.maxDelay
|
||||
}
|
||||
|
||||
calculated := time.Duration(backoff)
|
||||
if calculated > r.maxDelay {
|
||||
return r.maxDelay
|
||||
}
|
||||
|
||||
return calculated
|
||||
}
|
||||
|
||||
func (r *ItemExponentialFailureRateLimiter) NumRequeues(item interface{}) int {
|
||||
r.failuresLock.Lock()
|
||||
defer r.failuresLock.Unlock()
|
||||
|
||||
return r.failures[item]
|
||||
}
|
||||
|
||||
func (r *ItemExponentialFailureRateLimiter) Forget(item interface{}) {
|
||||
r.failuresLock.Lock()
|
||||
defer r.failuresLock.Unlock()
|
||||
|
||||
delete(r.failures, item)
|
||||
}
|
||||
|
||||
// ItemFastSlowRateLimiter does a quick retry for a certain number of attempts, then a slow retry after that
|
||||
type ItemFastSlowRateLimiter struct {
|
||||
failuresLock sync.Mutex
|
||||
failures map[interface{}]int
|
||||
|
||||
maxFastAttempts int
|
||||
fastDelay time.Duration
|
||||
slowDelay time.Duration
|
||||
}
|
||||
|
||||
var _ RateLimiter = &ItemFastSlowRateLimiter{}
|
||||
|
||||
func NewItemFastSlowRateLimiter(fastDelay, slowDelay time.Duration, maxFastAttempts int) RateLimiter {
|
||||
return &ItemFastSlowRateLimiter{
|
||||
failures: map[interface{}]int{},
|
||||
fastDelay: fastDelay,
|
||||
slowDelay: slowDelay,
|
||||
maxFastAttempts: maxFastAttempts,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ItemFastSlowRateLimiter) When(item interface{}) time.Duration {
|
||||
r.failuresLock.Lock()
|
||||
defer r.failuresLock.Unlock()
|
||||
|
||||
r.failures[item] = r.failures[item] + 1
|
||||
|
||||
if r.failures[item] <= r.maxFastAttempts {
|
||||
return r.fastDelay
|
||||
}
|
||||
|
||||
return r.slowDelay
|
||||
}
|
||||
|
||||
func (r *ItemFastSlowRateLimiter) NumRequeues(item interface{}) int {
|
||||
r.failuresLock.Lock()
|
||||
defer r.failuresLock.Unlock()
|
||||
|
||||
return r.failures[item]
|
||||
}
|
||||
|
||||
func (r *ItemFastSlowRateLimiter) Forget(item interface{}) {
|
||||
r.failuresLock.Lock()
|
||||
defer r.failuresLock.Unlock()
|
||||
|
||||
delete(r.failures, item)
|
||||
}
|
||||
|
||||
// MaxOfRateLimiter calls every RateLimiter and returns the worst case response
|
||||
// When used with a token bucket limiter, the burst could be apparently exceeded in cases where particular items
|
||||
// were separately delayed a longer time.
|
||||
type MaxOfRateLimiter struct {
|
||||
limiters []RateLimiter
|
||||
}
|
||||
|
||||
func (r *MaxOfRateLimiter) When(item interface{}) time.Duration {
|
||||
ret := time.Duration(0)
|
||||
for _, limiter := range r.limiters {
|
||||
curr := limiter.When(item)
|
||||
if curr > ret {
|
||||
ret = curr
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewMaxOfRateLimiter(limiters ...RateLimiter) RateLimiter {
|
||||
return &MaxOfRateLimiter{limiters: limiters}
|
||||
}
|
||||
|
||||
func (r *MaxOfRateLimiter) NumRequeues(item interface{}) int {
|
||||
ret := 0
|
||||
for _, limiter := range r.limiters {
|
||||
curr := limiter.NumRequeues(item)
|
||||
if curr > ret {
|
||||
ret = curr
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (r *MaxOfRateLimiter) Forget(item interface{}) {
|
||||
for _, limiter := range r.limiters {
|
||||
limiter.Forget(item)
|
||||
}
|
||||
}
|
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestItemExponentialFailureRateLimiter(t *testing.T) {
|
||||
limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1*time.Second)
|
||||
|
||||
if e, a := 1*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 2*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 4*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 8*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 16*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5, limiter.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := 1*time.Millisecond, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 2*time.Millisecond, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 2, limiter.NumRequeues("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
limiter.Forget("one")
|
||||
if e, a := 0, limiter.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 1*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestItemExponentialFailureRateLimiterOverFlow(t *testing.T) {
|
||||
limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1000*time.Second)
|
||||
for i := 0; i < 5; i++ {
|
||||
limiter.When("one")
|
||||
}
|
||||
if e, a := 32*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
limiter.When("overflow1")
|
||||
}
|
||||
if e, a := 1000*time.Second, limiter.When("overflow1"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
limiter = NewItemExponentialFailureRateLimiter(1*time.Minute, 1000*time.Hour)
|
||||
for i := 0; i < 2; i++ {
|
||||
limiter.When("two")
|
||||
}
|
||||
if e, a := 4*time.Minute, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
limiter.When("overflow2")
|
||||
}
|
||||
if e, a := 1000*time.Hour, limiter.When("overflow2"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestItemFastSlowRateLimiter(t *testing.T) {
|
||||
limiter := NewItemFastSlowRateLimiter(5*time.Millisecond, 10*time.Second, 3)
|
||||
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 10*time.Second, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 10*time.Second, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5, limiter.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := 5*time.Millisecond, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 2, limiter.NumRequeues("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
limiter.Forget("one")
|
||||
if e, a := 0, limiter.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMaxOfRateLimiter(t *testing.T) {
|
||||
limiter := NewMaxOfRateLimiter(
|
||||
NewItemFastSlowRateLimiter(5*time.Millisecond, 3*time.Second, 3),
|
||||
NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1*time.Second),
|
||||
)
|
||||
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 3*time.Second, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 3*time.Second, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5, limiter.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := 5*time.Millisecond, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 2, limiter.NumRequeues("two"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
limiter.Forget("one")
|
||||
if e, a := 0, limiter.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 5*time.Millisecond, limiter.When("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/util/clock"
|
||||
)
|
||||
|
||||
// DelayingInterface is an Interface that can Add an item at a later time. This makes it easier to
|
||||
// requeue items after failures without ending up in a hot-loop.
|
||||
type DelayingInterface interface {
|
||||
Interface
|
||||
// AddAfter adds an item to the workqueue after the indicated duration has passed
|
||||
AddAfter(item interface{}, duration time.Duration)
|
||||
}
|
||||
|
||||
// NewDelayingQueue constructs a new workqueue with delayed queuing ability
|
||||
func NewDelayingQueue() DelayingInterface {
|
||||
return newDelayingQueue(clock.RealClock{}, "")
|
||||
}
|
||||
|
||||
func NewNamedDelayingQueue(name string) DelayingInterface {
|
||||
return newDelayingQueue(clock.RealClock{}, name)
|
||||
}
|
||||
|
||||
func newDelayingQueue(clock clock.Clock, name string) DelayingInterface {
|
||||
ret := &delayingType{
|
||||
Interface: NewNamed(name),
|
||||
clock: clock,
|
||||
heartbeat: clock.Tick(maxWait),
|
||||
stopCh: make(chan struct{}),
|
||||
waitingTimeByEntry: map[t]time.Time{},
|
||||
waitingForAddCh: make(chan waitFor, 1000),
|
||||
metrics: newRetryMetrics(name),
|
||||
}
|
||||
|
||||
go ret.waitingLoop()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// delayingType wraps an Interface and provides delayed re-enquing
|
||||
type delayingType struct {
|
||||
Interface
|
||||
|
||||
// clock tracks time for delayed firing
|
||||
clock clock.Clock
|
||||
|
||||
// stopCh lets us signal a shutdown to the waiting loop
|
||||
stopCh chan struct{}
|
||||
|
||||
// heartbeat ensures we wait no more than maxWait before firing
|
||||
//
|
||||
// TODO: replace with Ticker (and add to clock) so this can be cleaned up.
|
||||
// clock.Tick will leak.
|
||||
heartbeat <-chan time.Time
|
||||
|
||||
// waitingForAdd is an ordered slice of items to be added to the contained work queue
|
||||
waitingForAdd []waitFor
|
||||
// waitingTimeByEntry holds wait time by entry, so we can lookup pre-existing indexes
|
||||
waitingTimeByEntry map[t]time.Time
|
||||
// waitingForAddCh is a buffered channel that feeds waitingForAdd
|
||||
waitingForAddCh chan waitFor
|
||||
|
||||
// metrics counts the number of retries
|
||||
metrics retryMetrics
|
||||
}
|
||||
|
||||
// waitFor holds the data to add and the time it should be added
|
||||
type waitFor struct {
|
||||
data t
|
||||
readyAt time.Time
|
||||
}
|
||||
|
||||
// ShutDown gives a way to shut off this queue
|
||||
func (q *delayingType) ShutDown() {
|
||||
q.Interface.ShutDown()
|
||||
close(q.stopCh)
|
||||
}
|
||||
|
||||
// AddAfter adds the given item to the work queue after the given delay
|
||||
func (q *delayingType) AddAfter(item interface{}, duration time.Duration) {
|
||||
// don't add if we're already shutting down
|
||||
if q.ShuttingDown() {
|
||||
return
|
||||
}
|
||||
|
||||
q.metrics.retry()
|
||||
|
||||
// immediately add things with no delay
|
||||
if duration <= 0 {
|
||||
q.Add(item)
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-q.stopCh:
|
||||
// unblock if ShutDown() is called
|
||||
case q.waitingForAddCh <- waitFor{data: item, readyAt: q.clock.Now().Add(duration)}:
|
||||
}
|
||||
}
|
||||
|
||||
// maxWait keeps a max bound on the wait time. It's just insurance against weird things happening.
|
||||
// Checking the queue every 10 seconds isn't expensive and we know that we'll never end up with an
|
||||
// expired item sitting for more than 10 seconds.
|
||||
const maxWait = 10 * time.Second
|
||||
|
||||
// waitingLoop runs until the workqueue is shutdown and keeps a check on the list of items to be added.
|
||||
func (q *delayingType) waitingLoop() {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
// Make a placeholder channel to use when there are no items in our list
|
||||
never := make(<-chan time.Time)
|
||||
|
||||
for {
|
||||
if q.Interface.ShuttingDown() {
|
||||
// discard waiting entries
|
||||
q.waitingForAdd = nil
|
||||
q.waitingTimeByEntry = nil
|
||||
return
|
||||
}
|
||||
|
||||
now := q.clock.Now()
|
||||
|
||||
// Add ready entries
|
||||
readyEntries := 0
|
||||
for _, entry := range q.waitingForAdd {
|
||||
if entry.readyAt.After(now) {
|
||||
break
|
||||
}
|
||||
q.Add(entry.data)
|
||||
delete(q.waitingTimeByEntry, entry.data)
|
||||
readyEntries++
|
||||
}
|
||||
q.waitingForAdd = q.waitingForAdd[readyEntries:]
|
||||
|
||||
// Set up a wait for the first item's readyAt (if one exists)
|
||||
nextReadyAt := never
|
||||
if len(q.waitingForAdd) > 0 {
|
||||
nextReadyAt = q.clock.After(q.waitingForAdd[0].readyAt.Sub(now))
|
||||
}
|
||||
|
||||
select {
|
||||
case <-q.stopCh:
|
||||
return
|
||||
|
||||
case <-q.heartbeat:
|
||||
// continue the loop, which will add ready items
|
||||
|
||||
case <-nextReadyAt:
|
||||
// continue the loop, which will add ready items
|
||||
|
||||
case waitEntry := <-q.waitingForAddCh:
|
||||
if waitEntry.readyAt.After(q.clock.Now()) {
|
||||
q.waitingForAdd = insert(q.waitingForAdd, q.waitingTimeByEntry, waitEntry)
|
||||
} else {
|
||||
q.Add(waitEntry.data)
|
||||
}
|
||||
|
||||
drained := false
|
||||
for !drained {
|
||||
select {
|
||||
case waitEntry := <-q.waitingForAddCh:
|
||||
if waitEntry.readyAt.After(q.clock.Now()) {
|
||||
q.waitingForAdd = insert(q.waitingForAdd, q.waitingTimeByEntry, waitEntry)
|
||||
} else {
|
||||
q.Add(waitEntry.data)
|
||||
}
|
||||
default:
|
||||
drained = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// inserts the given entry into the sorted entries list
|
||||
// same semantics as append()... the given slice may be modified,
|
||||
// and the returned value should be used
|
||||
//
|
||||
// TODO: This should probably be converted to use container/heap to improve
|
||||
// running time for a large number of items.
|
||||
func insert(entries []waitFor, knownEntries map[t]time.Time, entry waitFor) []waitFor {
|
||||
// if the entry is already in our retry list and the existing time is before the new one, just skip it
|
||||
existingTime, exists := knownEntries[entry.data]
|
||||
if exists && existingTime.Before(entry.readyAt) {
|
||||
return entries
|
||||
}
|
||||
|
||||
// if the entry exists and is scheduled for later, go ahead and remove the entry
|
||||
if exists {
|
||||
if existingIndex := findEntryIndex(entries, existingTime, entry.data); existingIndex >= 0 && existingIndex < len(entries) {
|
||||
entries = append(entries[:existingIndex], entries[existingIndex+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
insertionIndex := sort.Search(len(entries), func(i int) bool {
|
||||
return entry.readyAt.Before(entries[i].readyAt)
|
||||
})
|
||||
|
||||
// grow by 1
|
||||
entries = append(entries, waitFor{})
|
||||
// shift items from the insertion point to the end
|
||||
copy(entries[insertionIndex+1:], entries[insertionIndex:])
|
||||
// insert the record
|
||||
entries[insertionIndex] = entry
|
||||
|
||||
knownEntries[entry.data] = entry.readyAt
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
// findEntryIndex returns the index for an existing entry
|
||||
func findEntryIndex(entries []waitFor, existingTime time.Time, data t) int {
|
||||
index := sort.Search(len(entries), func(i int) bool {
|
||||
return entries[i].readyAt.After(existingTime) || existingTime == entries[i].readyAt
|
||||
})
|
||||
|
||||
// we know this is the earliest possible index, but there could be multiple with the same time
|
||||
// iterate from here to find the dupe
|
||||
for ; index < len(entries); index++ {
|
||||
if entries[index].data == data {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/util/clock"
|
||||
)
|
||||
|
||||
func TestSimpleQueue(t *testing.T) {
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
q := newDelayingQueue(fakeClock, "")
|
||||
|
||||
first := "foo"
|
||||
|
||||
q.AddAfter(first, 50*time.Millisecond)
|
||||
if err := waitForWaitingQueueToFill(q); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
|
||||
fakeClock.Step(60 * time.Millisecond)
|
||||
|
||||
if err := waitForAdded(q, 1); err != nil {
|
||||
t.Errorf("should have added")
|
||||
}
|
||||
item, _ := q.Get()
|
||||
q.Done(item)
|
||||
|
||||
// step past the next heartbeat
|
||||
fakeClock.Step(10 * time.Second)
|
||||
|
||||
err := wait.Poll(1*time.Millisecond, 30*time.Millisecond, func() (done bool, err error) {
|
||||
if q.Len() > 0 {
|
||||
return false, fmt.Errorf("added to queue")
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
if err != wait.ErrWaitTimeout {
|
||||
t.Errorf("expected timeout, got: %v", err)
|
||||
}
|
||||
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeduping(t *testing.T) {
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
q := newDelayingQueue(fakeClock, "")
|
||||
|
||||
first := "foo"
|
||||
|
||||
q.AddAfter(first, 50*time.Millisecond)
|
||||
if err := waitForWaitingQueueToFill(q); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
q.AddAfter(first, 70*time.Millisecond)
|
||||
if err := waitForWaitingQueueToFill(q); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
|
||||
// step past the first block, we should receive now
|
||||
fakeClock.Step(60 * time.Millisecond)
|
||||
if err := waitForAdded(q, 1); err != nil {
|
||||
t.Errorf("should have added")
|
||||
}
|
||||
item, _ := q.Get()
|
||||
q.Done(item)
|
||||
|
||||
// step past the second add
|
||||
fakeClock.Step(20 * time.Millisecond)
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
|
||||
// test again, but this time the earlier should override
|
||||
q.AddAfter(first, 50*time.Millisecond)
|
||||
q.AddAfter(first, 30*time.Millisecond)
|
||||
if err := waitForWaitingQueueToFill(q); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
|
||||
fakeClock.Step(40 * time.Millisecond)
|
||||
if err := waitForAdded(q, 1); err != nil {
|
||||
t.Errorf("should have added")
|
||||
}
|
||||
item, _ = q.Get()
|
||||
q.Done(item)
|
||||
|
||||
// step past the second add
|
||||
fakeClock.Step(20 * time.Millisecond)
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddTwoFireEarly(t *testing.T) {
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
q := newDelayingQueue(fakeClock, "")
|
||||
|
||||
first := "foo"
|
||||
second := "bar"
|
||||
third := "baz"
|
||||
|
||||
q.AddAfter(first, 1*time.Second)
|
||||
q.AddAfter(second, 50*time.Millisecond)
|
||||
if err := waitForWaitingQueueToFill(q); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
|
||||
fakeClock.Step(60 * time.Millisecond)
|
||||
|
||||
if err := waitForAdded(q, 1); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
item, _ := q.Get()
|
||||
if !reflect.DeepEqual(item, second) {
|
||||
t.Errorf("expected %v, got %v", second, item)
|
||||
}
|
||||
|
||||
q.AddAfter(third, 2*time.Second)
|
||||
|
||||
fakeClock.Step(1 * time.Second)
|
||||
if err := waitForAdded(q, 1); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
item, _ = q.Get()
|
||||
if !reflect.DeepEqual(item, first) {
|
||||
t.Errorf("expected %v, got %v", first, item)
|
||||
}
|
||||
|
||||
fakeClock.Step(2 * time.Second)
|
||||
if err := waitForAdded(q, 1); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
item, _ = q.Get()
|
||||
if !reflect.DeepEqual(item, third) {
|
||||
t.Errorf("expected %v, got %v", third, item)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCopyShifting(t *testing.T) {
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
q := newDelayingQueue(fakeClock, "")
|
||||
|
||||
first := "foo"
|
||||
second := "bar"
|
||||
third := "baz"
|
||||
|
||||
q.AddAfter(first, 1*time.Second)
|
||||
q.AddAfter(second, 500*time.Millisecond)
|
||||
q.AddAfter(third, 250*time.Millisecond)
|
||||
if err := waitForWaitingQueueToFill(q); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("should not have added")
|
||||
}
|
||||
|
||||
fakeClock.Step(2 * time.Second)
|
||||
|
||||
if err := waitForAdded(q, 3); err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
actualFirst, _ := q.Get()
|
||||
if !reflect.DeepEqual(actualFirst, third) {
|
||||
t.Errorf("expected %v, got %v", third, actualFirst)
|
||||
}
|
||||
actualSecond, _ := q.Get()
|
||||
if !reflect.DeepEqual(actualSecond, second) {
|
||||
t.Errorf("expected %v, got %v", second, actualSecond)
|
||||
}
|
||||
actualThird, _ := q.Get()
|
||||
if !reflect.DeepEqual(actualThird, first) {
|
||||
t.Errorf("expected %v, got %v", first, actualThird)
|
||||
}
|
||||
}
|
||||
|
||||
func waitForAdded(q DelayingInterface, depth int) error {
|
||||
return wait.Poll(1*time.Millisecond, 10*time.Second, func() (done bool, err error) {
|
||||
if q.Len() == depth {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
func waitForWaitingQueueToFill(q DelayingInterface) error {
|
||||
return wait.Poll(1*time.Millisecond, 10*time.Second, func() (done bool, err error) {
|
||||
if len(q.(*delayingType).waitingForAddCh) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// This file provides abstractions for setting the provider (e.g., prometheus)
|
||||
// of metrics.
|
||||
|
||||
type queueMetrics interface {
|
||||
add(item t)
|
||||
get(item t)
|
||||
done(item t)
|
||||
}
|
||||
|
||||
// GaugeMetric represents a single numerical value that can arbitrarily go up
|
||||
// and down.
|
||||
type GaugeMetric interface {
|
||||
Inc()
|
||||
Dec()
|
||||
}
|
||||
|
||||
// CounterMetric represents a single numerical value that only ever
|
||||
// goes up.
|
||||
type CounterMetric interface {
|
||||
Inc()
|
||||
}
|
||||
|
||||
// SummaryMetric captures individual observations.
|
||||
type SummaryMetric interface {
|
||||
Observe(float64)
|
||||
}
|
||||
|
||||
type noopMetric struct{}
|
||||
|
||||
func (noopMetric) Inc() {}
|
||||
func (noopMetric) Dec() {}
|
||||
func (noopMetric) Observe(float64) {}
|
||||
|
||||
type defaultQueueMetrics struct {
|
||||
// current depth of a workqueue
|
||||
depth GaugeMetric
|
||||
// total number of adds handled by a workqueue
|
||||
adds CounterMetric
|
||||
// how long an item stays in a workqueue
|
||||
latency SummaryMetric
|
||||
// how long processing an item from a workqueue takes
|
||||
workDuration SummaryMetric
|
||||
addTimes map[t]time.Time
|
||||
processingStartTimes map[t]time.Time
|
||||
}
|
||||
|
||||
func (m *defaultQueueMetrics) add(item t) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.adds.Inc()
|
||||
m.depth.Inc()
|
||||
if _, exists := m.addTimes[item]; !exists {
|
||||
m.addTimes[item] = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultQueueMetrics) get(item t) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.depth.Dec()
|
||||
m.processingStartTimes[item] = time.Now()
|
||||
if startTime, exists := m.addTimes[item]; exists {
|
||||
m.latency.Observe(sinceInMicroseconds(startTime))
|
||||
delete(m.addTimes, item)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultQueueMetrics) done(item t) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if startTime, exists := m.processingStartTimes[item]; exists {
|
||||
m.workDuration.Observe(sinceInMicroseconds(startTime))
|
||||
delete(m.processingStartTimes, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the time since the specified start in microseconds.
|
||||
func sinceInMicroseconds(start time.Time) float64 {
|
||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
||||
}
|
||||
|
||||
type retryMetrics interface {
|
||||
retry()
|
||||
}
|
||||
|
||||
type defaultRetryMetrics struct {
|
||||
retries CounterMetric
|
||||
}
|
||||
|
||||
func (m *defaultRetryMetrics) retry() {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.retries.Inc()
|
||||
}
|
||||
|
||||
// MetricsProvider generates various metrics used by the queue.
|
||||
type MetricsProvider interface {
|
||||
NewDepthMetric(name string) GaugeMetric
|
||||
NewAddsMetric(name string) CounterMetric
|
||||
NewLatencyMetric(name string) SummaryMetric
|
||||
NewWorkDurationMetric(name string) SummaryMetric
|
||||
NewRetriesMetric(name string) CounterMetric
|
||||
}
|
||||
|
||||
type noopMetricsProvider struct{}
|
||||
|
||||
func (_ noopMetricsProvider) NewDepthMetric(name string) GaugeMetric {
|
||||
return noopMetric{}
|
||||
}
|
||||
|
||||
func (_ noopMetricsProvider) NewAddsMetric(name string) CounterMetric {
|
||||
return noopMetric{}
|
||||
}
|
||||
|
||||
func (_ noopMetricsProvider) NewLatencyMetric(name string) SummaryMetric {
|
||||
return noopMetric{}
|
||||
}
|
||||
|
||||
func (_ noopMetricsProvider) NewWorkDurationMetric(name string) SummaryMetric {
|
||||
return noopMetric{}
|
||||
}
|
||||
|
||||
func (_ noopMetricsProvider) NewRetriesMetric(name string) CounterMetric {
|
||||
return noopMetric{}
|
||||
}
|
||||
|
||||
var metricsFactory = struct {
|
||||
metricsProvider MetricsProvider
|
||||
setProviders sync.Once
|
||||
}{
|
||||
metricsProvider: noopMetricsProvider{},
|
||||
}
|
||||
|
||||
func newQueueMetrics(name string) queueMetrics {
|
||||
var ret *defaultQueueMetrics
|
||||
if len(name) == 0 {
|
||||
return ret
|
||||
}
|
||||
return &defaultQueueMetrics{
|
||||
depth: metricsFactory.metricsProvider.NewDepthMetric(name),
|
||||
adds: metricsFactory.metricsProvider.NewAddsMetric(name),
|
||||
latency: metricsFactory.metricsProvider.NewLatencyMetric(name),
|
||||
workDuration: metricsFactory.metricsProvider.NewWorkDurationMetric(name),
|
||||
addTimes: map[t]time.Time{},
|
||||
processingStartTimes: map[t]time.Time{},
|
||||
}
|
||||
}
|
||||
|
||||
func newRetryMetrics(name string) retryMetrics {
|
||||
var ret *defaultRetryMetrics
|
||||
if len(name) == 0 {
|
||||
return ret
|
||||
}
|
||||
return &defaultRetryMetrics{
|
||||
retries: metricsFactory.metricsProvider.NewRetriesMetric(name),
|
||||
}
|
||||
}
|
||||
|
||||
// SetProvider sets the metrics provider of the metricsFactory.
|
||||
func SetProvider(metricsProvider MetricsProvider) {
|
||||
metricsFactory.setProviders.Do(func() {
|
||||
metricsFactory.metricsProvider = metricsProvider
|
||||
})
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
type DoWorkPieceFunc func(piece int)
|
||||
|
||||
// Parallelize is a very simple framework that allow for parallelizing
|
||||
// N independent pieces of work.
|
||||
func Parallelize(workers, pieces int, doWorkPiece DoWorkPieceFunc) {
|
||||
toProcess := make(chan int, pieces)
|
||||
for i := 0; i < pieces; i++ {
|
||||
toProcess <- i
|
||||
}
|
||||
close(toProcess)
|
||||
|
||||
if pieces < workers {
|
||||
workers = pieces
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(workers)
|
||||
for i := 0; i < workers; i++ {
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer wg.Done()
|
||||
for piece := range toProcess {
|
||||
doWorkPiece(piece)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Add(item interface{})
|
||||
Len() int
|
||||
Get() (item interface{}, shutdown bool)
|
||||
Done(item interface{})
|
||||
ShutDown()
|
||||
ShuttingDown() bool
|
||||
}
|
||||
|
||||
// New constructs a new workqueue (see the package comment).
|
||||
func New() *Type {
|
||||
return NewNamed("")
|
||||
}
|
||||
|
||||
func NewNamed(name string) *Type {
|
||||
return &Type{
|
||||
dirty: set{},
|
||||
processing: set{},
|
||||
cond: sync.NewCond(&sync.Mutex{}),
|
||||
metrics: newQueueMetrics(name),
|
||||
}
|
||||
}
|
||||
|
||||
// Type is a work queue (see the package comment).
|
||||
type Type struct {
|
||||
// queue defines the order in which we will work on items. Every
|
||||
// element of queue should be in the dirty set and not in the
|
||||
// processing set.
|
||||
queue []t
|
||||
|
||||
// dirty defines all of the items that need to be processed.
|
||||
dirty set
|
||||
|
||||
// Things that are currently being processed are in the processing set.
|
||||
// These things may be simultaneously in the dirty set. When we finish
|
||||
// processing something and remove it from this set, we'll check if
|
||||
// it's in the dirty set, and if so, add it to the queue.
|
||||
processing set
|
||||
|
||||
cond *sync.Cond
|
||||
|
||||
shuttingDown bool
|
||||
|
||||
metrics queueMetrics
|
||||
}
|
||||
|
||||
type empty struct{}
|
||||
type t interface{}
|
||||
type set map[t]empty
|
||||
|
||||
func (s set) has(item t) bool {
|
||||
_, exists := s[item]
|
||||
return exists
|
||||
}
|
||||
|
||||
func (s set) insert(item t) {
|
||||
s[item] = empty{}
|
||||
}
|
||||
|
||||
func (s set) delete(item t) {
|
||||
delete(s, item)
|
||||
}
|
||||
|
||||
// Add marks item as needing processing.
|
||||
func (q *Type) Add(item interface{}) {
|
||||
q.cond.L.Lock()
|
||||
defer q.cond.L.Unlock()
|
||||
if q.shuttingDown {
|
||||
return
|
||||
}
|
||||
if q.dirty.has(item) {
|
||||
return
|
||||
}
|
||||
|
||||
q.metrics.add(item)
|
||||
|
||||
q.dirty.insert(item)
|
||||
if q.processing.has(item) {
|
||||
return
|
||||
}
|
||||
|
||||
q.queue = append(q.queue, item)
|
||||
q.cond.Signal()
|
||||
}
|
||||
|
||||
// Len returns the current queue length, for informational purposes only. You
|
||||
// shouldn't e.g. gate a call to Add() or Get() on Len() being a particular
|
||||
// value, that can't be synchronized properly.
|
||||
func (q *Type) Len() int {
|
||||
q.cond.L.Lock()
|
||||
defer q.cond.L.Unlock()
|
||||
return len(q.queue)
|
||||
}
|
||||
|
||||
// Get blocks until it can return an item to be processed. If shutdown = true,
|
||||
// the caller should end their goroutine. You must call Done with item when you
|
||||
// have finished processing it.
|
||||
func (q *Type) Get() (item interface{}, shutdown bool) {
|
||||
q.cond.L.Lock()
|
||||
defer q.cond.L.Unlock()
|
||||
for len(q.queue) == 0 && !q.shuttingDown {
|
||||
q.cond.Wait()
|
||||
}
|
||||
if len(q.queue) == 0 {
|
||||
// We must be shutting down.
|
||||
return nil, true
|
||||
}
|
||||
|
||||
item, q.queue = q.queue[0], q.queue[1:]
|
||||
|
||||
q.metrics.get(item)
|
||||
|
||||
q.processing.insert(item)
|
||||
q.dirty.delete(item)
|
||||
|
||||
return item, false
|
||||
}
|
||||
|
||||
// Done marks item as done processing, and if it has been marked as dirty again
|
||||
// while it was being processed, it will be re-added to the queue for
|
||||
// re-processing.
|
||||
func (q *Type) Done(item interface{}) {
|
||||
q.cond.L.Lock()
|
||||
defer q.cond.L.Unlock()
|
||||
|
||||
q.metrics.done(item)
|
||||
|
||||
q.processing.delete(item)
|
||||
if q.dirty.has(item) {
|
||||
q.queue = append(q.queue, item)
|
||||
q.cond.Signal()
|
||||
}
|
||||
}
|
||||
|
||||
// ShutDown will cause q to ignore all new items added to it. As soon as the
|
||||
// worker goroutines have drained the existing items in the queue, they will be
|
||||
// instructed to exit.
|
||||
func (q *Type) ShutDown() {
|
||||
q.cond.L.Lock()
|
||||
defer q.cond.L.Unlock()
|
||||
q.shuttingDown = true
|
||||
q.cond.Broadcast()
|
||||
}
|
||||
|
||||
func (q *Type) ShuttingDown() bool {
|
||||
q.cond.L.Lock()
|
||||
defer q.cond.L.Unlock()
|
||||
|
||||
return q.shuttingDown
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
// RateLimitingInterface is an interface that rate limits items being added to the queue.
|
||||
type RateLimitingInterface interface {
|
||||
DelayingInterface
|
||||
|
||||
// AddRateLimited adds an item to the workqueue after the rate limiter says its ok
|
||||
AddRateLimited(item interface{})
|
||||
|
||||
// Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing
|
||||
// or for success, we'll stop the rate limiter from tracking it. This only clears the `rateLimiter`, you
|
||||
// still have to call `Done` on the queue.
|
||||
Forget(item interface{})
|
||||
|
||||
// NumRequeues returns back how many times the item was requeued
|
||||
NumRequeues(item interface{}) int
|
||||
}
|
||||
|
||||
// NewRateLimitingQueue constructs a new workqueue with rateLimited queuing ability
|
||||
// Remember to call Forget! If you don't, you may end up tracking failures forever.
|
||||
func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface {
|
||||
return &rateLimitingType{
|
||||
DelayingInterface: NewDelayingQueue(),
|
||||
rateLimiter: rateLimiter,
|
||||
}
|
||||
}
|
||||
|
||||
func NewNamedRateLimitingQueue(rateLimiter RateLimiter, name string) RateLimitingInterface {
|
||||
return &rateLimitingType{
|
||||
DelayingInterface: NewNamedDelayingQueue(name),
|
||||
rateLimiter: rateLimiter,
|
||||
}
|
||||
}
|
||||
|
||||
// rateLimitingType wraps an Interface and provides rateLimited re-enquing
|
||||
type rateLimitingType struct {
|
||||
DelayingInterface
|
||||
|
||||
rateLimiter RateLimiter
|
||||
}
|
||||
|
||||
// AddRateLimited AddAfter's the item based on the time when the rate limiter says its ok
|
||||
func (q *rateLimitingType) AddRateLimited(item interface{}) {
|
||||
q.DelayingInterface.AddAfter(item, q.rateLimiter.When(item))
|
||||
}
|
||||
|
||||
func (q *rateLimitingType) NumRequeues(item interface{}) int {
|
||||
return q.rateLimiter.NumRequeues(item)
|
||||
}
|
||||
|
||||
func (q *rateLimitingType) Forget(item interface{}) {
|
||||
q.rateLimiter.Forget(item)
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/util/clock"
|
||||
)
|
||||
|
||||
func TestRateLimitingQueue(t *testing.T) {
|
||||
limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1*time.Second)
|
||||
queue := NewRateLimitingQueue(limiter).(*rateLimitingType)
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
delayingQueue := &delayingType{
|
||||
Interface: New(),
|
||||
clock: fakeClock,
|
||||
heartbeat: fakeClock.Tick(maxWait),
|
||||
stopCh: make(chan struct{}),
|
||||
waitingForAddCh: make(chan waitFor, 1000),
|
||||
metrics: newRetryMetrics(""),
|
||||
}
|
||||
queue.DelayingInterface = delayingQueue
|
||||
|
||||
queue.AddRateLimited("one")
|
||||
waitEntry := <-delayingQueue.waitingForAddCh
|
||||
if e, a := 1*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
queue.AddRateLimited("one")
|
||||
waitEntry = <-delayingQueue.waitingForAddCh
|
||||
if e, a := 2*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 2, queue.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
queue.AddRateLimited("two")
|
||||
waitEntry = <-delayingQueue.waitingForAddCh
|
||||
if e, a := 1*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
queue.AddRateLimited("two")
|
||||
waitEntry = <-delayingQueue.waitingForAddCh
|
||||
if e, a := 2*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
queue.Forget("one")
|
||||
if e, a := 0, queue.NumRequeues("one"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
queue.AddRateLimited("one")
|
||||
waitEntry = <-delayingQueue.waitingForAddCh
|
||||
if e, a := 1*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 workqueue
|
||||
|
||||
import "time"
|
||||
|
||||
type TimedWorkQueue struct {
|
||||
*Type
|
||||
}
|
||||
|
||||
type TimedWorkQueueItem struct {
|
||||
StartTime time.Time
|
||||
Object interface{}
|
||||
}
|
||||
|
||||
func NewTimedWorkQueue() *TimedWorkQueue {
|
||||
return &TimedWorkQueue{New()}
|
||||
}
|
||||
|
||||
// Add adds the obj along with the current timestamp to the queue.
|
||||
func (q TimedWorkQueue) Add(timedItem *TimedWorkQueueItem) {
|
||||
q.Type.Add(timedItem)
|
||||
}
|
||||
|
||||
// Get gets the obj along with its timestamp from the queue.
|
||||
func (q TimedWorkQueue) Get() (timedItem *TimedWorkQueueItem, shutdown bool) {
|
||||
origin, shutdown := q.Type.Get()
|
||||
if origin == nil {
|
||||
return nil, shutdown
|
||||
}
|
||||
timedItem, _ = origin.(*TimedWorkQueueItem)
|
||||
return timedItem, shutdown
|
||||
}
|
||||
|
||||
func (q TimedWorkQueue) Done(timedItem *TimedWorkQueueItem) error {
|
||||
q.Type.Done(timedItem)
|
||||
return nil
|
||||
}
|
@@ -1,501 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package json is forked from the Go standard library to enable us to find the
|
||||
// field of a struct that a given JSON key maps to.
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Finds the patchStrategy and patchMergeKey struct tag fields on a given
|
||||
// struct field given the struct type and the JSON name of the field.
|
||||
// TODO: fix the returned errors to be introspectable.
|
||||
func LookupPatchMetadata(t reflect.Type, jsonField string) (reflect.Type, string, string, error) {
|
||||
if t.Kind() == reflect.Map {
|
||||
return t.Elem(), "", "", nil
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil, "", "", fmt.Errorf("merging an object in json but data type is not map or struct, instead is: %s",
|
||||
t.Kind().String())
|
||||
}
|
||||
jf := []byte(jsonField)
|
||||
// Find the field that the JSON library would use.
|
||||
var f *field
|
||||
fields := cachedTypeFields(t)
|
||||
for i := range fields {
|
||||
ff := &fields[i]
|
||||
if bytes.Equal(ff.nameBytes, jf) {
|
||||
f = ff
|
||||
break
|
||||
}
|
||||
// Do case-insensitive comparison.
|
||||
if f == nil && ff.equalFold(ff.nameBytes, jf) {
|
||||
f = ff
|
||||
}
|
||||
}
|
||||
if f != nil {
|
||||
// Find the reflect.Value of the most preferential struct field.
|
||||
tjf := t.Field(f.index[0])
|
||||
// we must navigate down all the anonymously included structs in the chain
|
||||
for i := 1; i < len(f.index); i++ {
|
||||
tjf = tjf.Type.Field(f.index[i])
|
||||
}
|
||||
patchStrategy := tjf.Tag.Get("patchStrategy")
|
||||
patchMergeKey := tjf.Tag.Get("patchMergeKey")
|
||||
return tjf.Type, patchStrategy, patchMergeKey, nil
|
||||
}
|
||||
return nil, "", "", fmt.Errorf("unable to find api field in struct %s for the json field %q", t.Name(), jsonField)
|
||||
}
|
||||
|
||||
// A field represents a single field found in a struct.
|
||||
type field struct {
|
||||
name string
|
||||
nameBytes []byte // []byte(name)
|
||||
equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
|
||||
|
||||
tag bool
|
||||
// index is the sequence of indexes from the containing type fields to this field.
|
||||
// it is a slice because anonymous structs will need multiple navigation steps to correctly
|
||||
// resolve the proper fields
|
||||
index []int
|
||||
typ reflect.Type
|
||||
omitEmpty bool
|
||||
quoted bool
|
||||
}
|
||||
|
||||
func (f field) String() string {
|
||||
return fmt.Sprintf("{name: %s, type: %v, tag: %v, index: %v, omitEmpty: %v, quoted: %v}", f.name, f.typ, f.tag, f.index, f.omitEmpty, f.quoted)
|
||||
}
|
||||
|
||||
func fillField(f field) field {
|
||||
f.nameBytes = []byte(f.name)
|
||||
f.equalFold = foldFunc(f.nameBytes)
|
||||
return f
|
||||
}
|
||||
|
||||
// byName sorts field by name, breaking ties with depth,
|
||||
// then breaking ties with "name came from json tag", then
|
||||
// breaking ties with index sequence.
|
||||
type byName []field
|
||||
|
||||
func (x byName) Len() int { return len(x) }
|
||||
|
||||
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
func (x byName) Less(i, j int) bool {
|
||||
if x[i].name != x[j].name {
|
||||
return x[i].name < x[j].name
|
||||
}
|
||||
if len(x[i].index) != len(x[j].index) {
|
||||
return len(x[i].index) < len(x[j].index)
|
||||
}
|
||||
if x[i].tag != x[j].tag {
|
||||
return x[i].tag
|
||||
}
|
||||
return byIndex(x).Less(i, j)
|
||||
}
|
||||
|
||||
// byIndex sorts field by index sequence.
|
||||
type byIndex []field
|
||||
|
||||
func (x byIndex) Len() int { return len(x) }
|
||||
|
||||
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
func (x byIndex) Less(i, j int) bool {
|
||||
for k, xik := range x[i].index {
|
||||
if k >= len(x[j].index) {
|
||||
return false
|
||||
}
|
||||
if xik != x[j].index[k] {
|
||||
return xik < x[j].index[k]
|
||||
}
|
||||
}
|
||||
return len(x[i].index) < len(x[j].index)
|
||||
}
|
||||
|
||||
// typeFields returns a list of fields that JSON should recognize for the given type.
|
||||
// The algorithm is breadth-first search over the set of structs to include - the top struct
|
||||
// and then any reachable anonymous structs.
|
||||
func typeFields(t reflect.Type) []field {
|
||||
// Anonymous fields to explore at the current level and the next.
|
||||
current := []field{}
|
||||
next := []field{{typ: t}}
|
||||
|
||||
// Count of queued names for current level and the next.
|
||||
count := map[reflect.Type]int{}
|
||||
nextCount := map[reflect.Type]int{}
|
||||
|
||||
// Types already visited at an earlier level.
|
||||
visited := map[reflect.Type]bool{}
|
||||
|
||||
// Fields found.
|
||||
var fields []field
|
||||
|
||||
for len(next) > 0 {
|
||||
current, next = next, current[:0]
|
||||
count, nextCount = nextCount, map[reflect.Type]int{}
|
||||
|
||||
for _, f := range current {
|
||||
if visited[f.typ] {
|
||||
continue
|
||||
}
|
||||
visited[f.typ] = true
|
||||
|
||||
// Scan f.typ for fields to include.
|
||||
for i := 0; i < f.typ.NumField(); i++ {
|
||||
sf := f.typ.Field(i)
|
||||
if sf.PkgPath != "" { // unexported
|
||||
continue
|
||||
}
|
||||
tag := sf.Tag.Get("json")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
name, opts := parseTag(tag)
|
||||
if !isValidTag(name) {
|
||||
name = ""
|
||||
}
|
||||
index := make([]int, len(f.index)+1)
|
||||
copy(index, f.index)
|
||||
index[len(f.index)] = i
|
||||
|
||||
ft := sf.Type
|
||||
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
|
||||
// Follow pointer.
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
// Record found field and index sequence.
|
||||
if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
|
||||
tagged := name != ""
|
||||
if name == "" {
|
||||
name = sf.Name
|
||||
}
|
||||
fields = append(fields, fillField(field{
|
||||
name: name,
|
||||
tag: tagged,
|
||||
index: index,
|
||||
typ: ft,
|
||||
omitEmpty: opts.Contains("omitempty"),
|
||||
quoted: opts.Contains("string"),
|
||||
}))
|
||||
if count[f.typ] > 1 {
|
||||
// If there were multiple instances, add a second,
|
||||
// so that the annihilation code will see a duplicate.
|
||||
// It only cares about the distinction between 1 or 2,
|
||||
// so don't bother generating any more copies.
|
||||
fields = append(fields, fields[len(fields)-1])
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Record new anonymous struct to explore in next round.
|
||||
nextCount[ft]++
|
||||
if nextCount[ft] == 1 {
|
||||
next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(byName(fields))
|
||||
|
||||
// Delete all fields that are hidden by the Go rules for embedded fields,
|
||||
// except that fields with JSON tags are promoted.
|
||||
|
||||
// The fields are sorted in primary order of name, secondary order
|
||||
// of field index length. Loop over names; for each name, delete
|
||||
// hidden fields by choosing the one dominant field that survives.
|
||||
out := fields[:0]
|
||||
for advance, i := 0, 0; i < len(fields); i += advance {
|
||||
// One iteration per name.
|
||||
// Find the sequence of fields with the name of this first field.
|
||||
fi := fields[i]
|
||||
name := fi.name
|
||||
for advance = 1; i+advance < len(fields); advance++ {
|
||||
fj := fields[i+advance]
|
||||
if fj.name != name {
|
||||
break
|
||||
}
|
||||
}
|
||||
if advance == 1 { // Only one field with this name
|
||||
out = append(out, fi)
|
||||
continue
|
||||
}
|
||||
dominant, ok := dominantField(fields[i : i+advance])
|
||||
if ok {
|
||||
out = append(out, dominant)
|
||||
}
|
||||
}
|
||||
|
||||
fields = out
|
||||
sort.Sort(byIndex(fields))
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
// dominantField looks through the fields, all of which are known to
|
||||
// have the same name, to find the single field that dominates the
|
||||
// others using Go's embedding rules, modified by the presence of
|
||||
// JSON tags. If there are multiple top-level fields, the boolean
|
||||
// will be false: This condition is an error in Go and we skip all
|
||||
// the fields.
|
||||
func dominantField(fields []field) (field, bool) {
|
||||
// The fields are sorted in increasing index-length order. The winner
|
||||
// must therefore be one with the shortest index length. Drop all
|
||||
// longer entries, which is easy: just truncate the slice.
|
||||
length := len(fields[0].index)
|
||||
tagged := -1 // Index of first tagged field.
|
||||
for i, f := range fields {
|
||||
if len(f.index) > length {
|
||||
fields = fields[:i]
|
||||
break
|
||||
}
|
||||
if f.tag {
|
||||
if tagged >= 0 {
|
||||
// Multiple tagged fields at the same level: conflict.
|
||||
// Return no field.
|
||||
return field{}, false
|
||||
}
|
||||
tagged = i
|
||||
}
|
||||
}
|
||||
if tagged >= 0 {
|
||||
return fields[tagged], true
|
||||
}
|
||||
// All remaining fields have the same length. If there's more than one,
|
||||
// we have a conflict (two fields named "X" at the same level) and we
|
||||
// return no field.
|
||||
if len(fields) > 1 {
|
||||
return field{}, false
|
||||
}
|
||||
return fields[0], true
|
||||
}
|
||||
|
||||
var fieldCache struct {
|
||||
sync.RWMutex
|
||||
m map[reflect.Type][]field
|
||||
}
|
||||
|
||||
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
|
||||
func cachedTypeFields(t reflect.Type) []field {
|
||||
fieldCache.RLock()
|
||||
f := fieldCache.m[t]
|
||||
fieldCache.RUnlock()
|
||||
if f != nil {
|
||||
return f
|
||||
}
|
||||
|
||||
// Compute fields without lock.
|
||||
// Might duplicate effort but won't hold other computations back.
|
||||
f = typeFields(t)
|
||||
if f == nil {
|
||||
f = []field{}
|
||||
}
|
||||
|
||||
fieldCache.Lock()
|
||||
if fieldCache.m == nil {
|
||||
fieldCache.m = map[reflect.Type][]field{}
|
||||
}
|
||||
fieldCache.m[t] = f
|
||||
fieldCache.Unlock()
|
||||
return f
|
||||
}
|
||||
|
||||
func isValidTag(s string) bool {
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
for _, c := range s {
|
||||
switch {
|
||||
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
|
||||
// Backslash and quote chars are reserved, but
|
||||
// otherwise any punctuation chars are allowed
|
||||
// in a tag name.
|
||||
default:
|
||||
if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
|
||||
kelvin = '\u212a'
|
||||
smallLongEss = '\u017f'
|
||||
)
|
||||
|
||||
// foldFunc returns one of four different case folding equivalence
|
||||
// functions, from most general (and slow) to fastest:
|
||||
//
|
||||
// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
|
||||
// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
|
||||
// 3) asciiEqualFold, no special, but includes non-letters (including _)
|
||||
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
||||
//
|
||||
// The letters S and K are special because they map to 3 runes, not just 2:
|
||||
// * S maps to s and to U+017F 'ſ' Latin small letter long s
|
||||
// * k maps to K and to U+212A 'K' Kelvin sign
|
||||
// See http://play.golang.org/p/tTxjOc0OGo
|
||||
//
|
||||
// The returned function is specialized for matching against s and
|
||||
// should only be given s. It's not curried for performance reasons.
|
||||
func foldFunc(s []byte) func(s, t []byte) bool {
|
||||
nonLetter := false
|
||||
special := false // special letter
|
||||
for _, b := range s {
|
||||
if b >= utf8.RuneSelf {
|
||||
return bytes.EqualFold
|
||||
}
|
||||
upper := b & caseMask
|
||||
if upper < 'A' || upper > 'Z' {
|
||||
nonLetter = true
|
||||
} else if upper == 'K' || upper == 'S' {
|
||||
// See above for why these letters are special.
|
||||
special = true
|
||||
}
|
||||
}
|
||||
if special {
|
||||
return equalFoldRight
|
||||
}
|
||||
if nonLetter {
|
||||
return asciiEqualFold
|
||||
}
|
||||
return simpleLetterEqualFold
|
||||
}
|
||||
|
||||
// equalFoldRight is a specialization of bytes.EqualFold when s is
|
||||
// known to be all ASCII (including punctuation), but contains an 's',
|
||||
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
|
||||
// See comments on foldFunc.
|
||||
func equalFoldRight(s, t []byte) bool {
|
||||
for _, sb := range s {
|
||||
if len(t) == 0 {
|
||||
return false
|
||||
}
|
||||
tb := t[0]
|
||||
if tb < utf8.RuneSelf {
|
||||
if sb != tb {
|
||||
sbUpper := sb & caseMask
|
||||
if 'A' <= sbUpper && sbUpper <= 'Z' {
|
||||
if sbUpper != tb&caseMask {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
t = t[1:]
|
||||
continue
|
||||
}
|
||||
// sb is ASCII and t is not. t must be either kelvin
|
||||
// sign or long s; sb must be s, S, k, or K.
|
||||
tr, size := utf8.DecodeRune(t)
|
||||
switch sb {
|
||||
case 's', 'S':
|
||||
if tr != smallLongEss {
|
||||
return false
|
||||
}
|
||||
case 'k', 'K':
|
||||
if tr != kelvin {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
t = t[size:]
|
||||
|
||||
}
|
||||
if len(t) > 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// asciiEqualFold is a specialization of bytes.EqualFold for use when
|
||||
// s is all ASCII (but may contain non-letters) and contains no
|
||||
// special-folding letters.
|
||||
// See comments on foldFunc.
|
||||
func asciiEqualFold(s, t []byte) bool {
|
||||
if len(s) != len(t) {
|
||||
return false
|
||||
}
|
||||
for i, sb := range s {
|
||||
tb := t[i]
|
||||
if sb == tb {
|
||||
continue
|
||||
}
|
||||
if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
|
||||
if sb&caseMask != tb&caseMask {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// simpleLetterEqualFold is a specialization of bytes.EqualFold for
|
||||
// use when s is all ASCII letters (no underscores, etc) and also
|
||||
// doesn't contain 'k', 'K', 's', or 'S'.
|
||||
// See comments on foldFunc.
|
||||
func simpleLetterEqualFold(s, t []byte) bool {
|
||||
if len(s) != len(t) {
|
||||
return false
|
||||
}
|
||||
for i, b := range s {
|
||||
if b&caseMask != t[i]&caseMask {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// tagOptions is the string following a comma in a struct field's "json"
|
||||
// tag, or the empty string. It does not include the leading comma.
|
||||
type tagOptions string
|
||||
|
||||
// parseTag splits a struct field's json tag into its name and
|
||||
// comma-separated options.
|
||||
func parseTag(tag string) (string, tagOptions) {
|
||||
if idx := strings.Index(tag, ","); idx != -1 {
|
||||
return tag[:idx], tagOptions(tag[idx+1:])
|
||||
}
|
||||
return tag, tagOptions("")
|
||||
}
|
||||
|
||||
// Contains reports whether a comma-separated list of options
|
||||
// contains a particular substr flag. substr must be surrounded by a
|
||||
// string boundary or commas.
|
||||
func (o tagOptions) Contains(optionName string) bool {
|
||||
if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
s := string(o)
|
||||
for s != "" {
|
||||
var next string
|
||||
i := strings.Index(s, ",")
|
||||
if i >= 0 {
|
||||
s, next = s[:i], s[i+1:]
|
||||
}
|
||||
if s == optionName {
|
||||
return true
|
||||
}
|
||||
s = next
|
||||
}
|
||||
return false
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FROM: http://golang.org/src/net/http/client.go
|
||||
// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
|
||||
// return true if the string includes a port.
|
||||
func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
|
||||
|
||||
// FROM: http://golang.org/src/net/http/transport.go
|
||||
var portMap = map[string]string{
|
||||
"http": "80",
|
||||
"https": "443",
|
||||
}
|
||||
|
||||
// FROM: http://golang.org/src/net/http/transport.go
|
||||
// canonicalAddr returns url.Host but always with a ":port" suffix
|
||||
func CanonicalAddr(url *url.URL) string {
|
||||
addr := url.Host
|
||||
if !hasPort(addr) {
|
||||
return addr + ":" + portMap[url.Scheme]
|
||||
}
|
||||
return addr
|
||||
}
|
@@ -28,9 +28,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
_ "k8s.io/client-go/pkg/api/install" // To register api.Pod used in tests below
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/client-go/pkg/util/strategicpatch"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/util/clock"
|
||||
)
|
||||
|
@@ -27,8 +27,8 @@ import (
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/client-go/pkg/util/strategicpatch"
|
||||
"k8s.io/client-go/util/clock"
|
||||
)
|
||||
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/pkg/third_party/forked/golang/template"
|
||||
"k8s.io/client-go/third_party/forked/golang/template"
|
||||
)
|
||||
|
||||
type JSONPath struct {
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/pkg/util/workqueue"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
func TestBasic(t *testing.T) {
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user