Upgrade k8s package verison (#5358)
* upgrade k8s package version Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> * Script upgrade and code formatting. Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
47
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go
generated
vendored
Normal file
47
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2021 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 eventclock
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
baseclock "k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// EventFunc does some work that needs to be done at or after the
|
||||
// given time.
|
||||
type EventFunc func(time.Time)
|
||||
|
||||
// EventClock is an active clock abstraction for use in code that is
|
||||
// testable with a fake clock that itself determines how time may be
|
||||
// advanced. The timing paradigm is invoking EventFuncs rather than
|
||||
// synchronizing through channels, so that the fake clock has a handle
|
||||
// on when associated activity is done.
|
||||
type Interface interface {
|
||||
baseclock.PassiveClock
|
||||
|
||||
// Sleep returns after the given duration (or more).
|
||||
Sleep(d time.Duration)
|
||||
|
||||
// EventAfterDuration invokes the given EventFunc after the given duration (or more),
|
||||
// passing the time when the invocation was launched.
|
||||
EventAfterDuration(f EventFunc, d time.Duration)
|
||||
|
||||
// EventAfterTime invokes the given EventFunc at the given time or later,
|
||||
// passing the time when the invocation was launched.
|
||||
EventAfterTime(f EventFunc, t time.Time)
|
||||
}
|
||||
44
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go
generated
vendored
Normal file
44
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2021 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 eventclock
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// RealEventClock fires event on real world time
|
||||
type Real struct {
|
||||
clock.RealClock
|
||||
}
|
||||
|
||||
var _ Interface = Real{}
|
||||
|
||||
// EventAfterDuration schedules an EventFunc
|
||||
func (Real) EventAfterDuration(f EventFunc, d time.Duration) {
|
||||
ch := time.After(d)
|
||||
go func() {
|
||||
t := <-ch
|
||||
f(t)
|
||||
}()
|
||||
}
|
||||
|
||||
// EventAfterTime schedules an EventFunc
|
||||
func (r Real) EventAfterTime(f EventFunc, t time.Time) {
|
||||
r.EventAfterDuration(f, time.Until(t))
|
||||
}
|
||||
12
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go
generated
vendored
12
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go
generated
vendored
@@ -21,17 +21,16 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// Integrator computes the moments of some variable X over time as
|
||||
// read from a particular clock. The integrals start when the
|
||||
// Integrator is created, and ends at the latest operation on the
|
||||
// Integrator. As a `metrics.TimedObserver` this fixes X1=1 and
|
||||
// ignores attempts to change X1.
|
||||
// Integrator.
|
||||
type Integrator interface {
|
||||
metrics.TimedObserver
|
||||
Set(float64)
|
||||
Add(float64)
|
||||
|
||||
GetResults() IntegratorResults
|
||||
|
||||
@@ -70,9 +69,6 @@ func NewIntegrator(clock clock.PassiveClock) Integrator {
|
||||
}
|
||||
}
|
||||
|
||||
func (igr *integrator) SetX1(x1 float64) {
|
||||
}
|
||||
|
||||
func (igr *integrator) Set(x float64) {
|
||||
igr.Lock()
|
||||
igr.setLocked(x)
|
||||
|
||||
14
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go
generated
vendored
14
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go
generated
vendored
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/debug"
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/request"
|
||||
)
|
||||
|
||||
// QueueSetFactory is used to create QueueSet objects. Creation, like
|
||||
@@ -30,8 +31,11 @@ import (
|
||||
// are separated so that errors from the first phase can be found
|
||||
// before committing to a concurrency allotment for the second.
|
||||
type QueueSetFactory interface {
|
||||
// BeginConstruction does the first phase of creating a QueueSet
|
||||
BeginConstruction(QueuingConfig, metrics.TimedObserverPair) (QueueSetCompleter, error)
|
||||
// BeginConstruction does the first phase of creating a QueueSet.
|
||||
// The RatioedGaugePair observes number of requests,
|
||||
// execution covering just the regular phase.
|
||||
// The RatioedGauge observes number of seats occupied through all phases of execution.
|
||||
BeginConstruction(QueuingConfig, metrics.RatioedGaugePair, metrics.RatioedGauge) (QueueSetCompleter, error)
|
||||
}
|
||||
|
||||
// QueueSetCompleter finishes the two-step process of creating or
|
||||
@@ -80,11 +84,7 @@ type QueueSet interface {
|
||||
// was idle at the moment of the return. Otherwise idle==false
|
||||
// and the client must call the Finish method of the Request
|
||||
// exactly once.
|
||||
StartRequest(ctx context.Context, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn QueueNoteFn) (req Request, idle bool)
|
||||
|
||||
// UpdateObservations makes sure any time-based statistics have
|
||||
// caught up with the current clock reading
|
||||
UpdateObservations()
|
||||
StartRequest(ctx context.Context, width *request.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn QueueNoteFn) (req Request, idle bool)
|
||||
|
||||
// Dump saves and returns the instant internal state of the queue-set.
|
||||
// Note that dumping process will stop the queue-set from proceeding
|
||||
|
||||
109
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go
generated
vendored
109
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go
generated
vendored
@@ -16,47 +16,15 @@ limitations under the License.
|
||||
|
||||
package promise
|
||||
|
||||
// This file defines interfaces for promises and futures and related
|
||||
// things. These are about coordination among multiple goroutines and
|
||||
// so are safe for concurrent calls --- although moderated in some
|
||||
// cases by a requirement that the caller hold a certain lock.
|
||||
|
||||
// Readable represents a variable that is initially not set and later
|
||||
// becomes set. Some instances may be set to multiple values in
|
||||
// series. A Readable for a variable that can only get one value is
|
||||
// commonly known as a "future".
|
||||
type Readable interface {
|
||||
// Get reads the current value of this variable. If this variable
|
||||
// is not set yet then this call blocks until this variable gets a
|
||||
// value.
|
||||
// WriteOnce represents a variable that is initially not set and can
|
||||
// be set once and is readable. This is the common meaning for
|
||||
// "promise".
|
||||
type WriteOnce interface {
|
||||
// Get reads the current value of this variable. If this
|
||||
// variable is not set yet then this call blocks until this
|
||||
// variable gets a value.
|
||||
Get() interface{}
|
||||
|
||||
// IsSet returns immediately with an indication of whether this
|
||||
// variable has been set.
|
||||
IsSet() bool
|
||||
}
|
||||
|
||||
// LockingReadable is a Readable whose implementation is protected by
|
||||
// a lock
|
||||
type LockingReadable interface {
|
||||
Readable
|
||||
|
||||
// GetLocked is like Get but the caller must already hold the
|
||||
// lock. GetLocked may release, and later re-acquire, the lock
|
||||
// any number of times. Get may acquire, and later release, the
|
||||
// lock any number of times.
|
||||
GetLocked() interface{}
|
||||
|
||||
// IsSetLocked is like IsSet but the caller must already hold the
|
||||
// lock. IsSetLocked may release, and later re-acquire, the lock
|
||||
// any number of times. IsSet may acquire, and later release, the
|
||||
// lock any number of times.
|
||||
IsSetLocked() bool
|
||||
}
|
||||
|
||||
// WriteOnceOnly represents a variable that is initially not set and
|
||||
// can be set once.
|
||||
type WriteOnceOnly interface {
|
||||
// Set normally writes a value into this variable, unblocks every
|
||||
// goroutine waiting for this variable to have a value, and
|
||||
// returns true. In the unhappy case that this variable is
|
||||
@@ -64,66 +32,3 @@ type WriteOnceOnly interface {
|
||||
// variable's value.
|
||||
Set(interface{}) bool
|
||||
}
|
||||
|
||||
// WriteOnce represents a variable that is initially not set and can
|
||||
// be set once and is readable. This is the common meaning for
|
||||
// "promise".
|
||||
type WriteOnce interface {
|
||||
Readable
|
||||
WriteOnceOnly
|
||||
}
|
||||
|
||||
// LockingWriteOnceOnly is a WriteOnceOnly whose implementation is
|
||||
// protected by a lock.
|
||||
type LockingWriteOnceOnly interface {
|
||||
WriteOnceOnly
|
||||
|
||||
// SetLocked is like Set but the caller must already hold the
|
||||
// lock. SetLocked may release, and later re-acquire, the lock
|
||||
// any number of times. Set may acquire, and later release, the
|
||||
// lock any number of times
|
||||
SetLocked(interface{}) bool
|
||||
}
|
||||
|
||||
// LockingWriteOnce is a WriteOnce whose implementation is protected
|
||||
// by a lock.
|
||||
type LockingWriteOnce interface {
|
||||
LockingReadable
|
||||
LockingWriteOnceOnly
|
||||
}
|
||||
|
||||
// WriteMultipleOnly represents a variable that is initially not set
|
||||
// and can be set one or more times (unlike a traditional "promise",
|
||||
// which can be written only once).
|
||||
type WriteMultipleOnly interface {
|
||||
// Set writes a value into this variable and unblocks every
|
||||
// goroutine waiting for this variable to have a value
|
||||
Set(interface{})
|
||||
}
|
||||
|
||||
// WriteMultiple represents a variable that is initially not set and
|
||||
// can be set one or more times (unlike a traditional "promise", which
|
||||
// can be written only once) and is readable.
|
||||
type WriteMultiple interface {
|
||||
Readable
|
||||
WriteMultipleOnly
|
||||
}
|
||||
|
||||
// LockingWriteMultipleOnly is a WriteMultipleOnly whose
|
||||
// implementation is protected by a lock.
|
||||
type LockingWriteMultipleOnly interface {
|
||||
WriteMultipleOnly
|
||||
|
||||
// SetLocked is like Set but the caller must already hold the
|
||||
// lock. SetLocked may release, and later re-acquire, the lock
|
||||
// any number of times. Set may acquire, and later release, the
|
||||
// lock any number of times
|
||||
SetLocked(interface{})
|
||||
}
|
||||
|
||||
// LockingWriteMultiple is a WriteMultiple whose implementation is
|
||||
// protected by a lock.
|
||||
type LockingWriteMultiple interface {
|
||||
LockingReadable
|
||||
LockingWriteMultipleOnly
|
||||
}
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 lockingpromise
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/counter"
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise"
|
||||
)
|
||||
|
||||
// promisoid is the data and behavior common to all the promise-like
|
||||
// abstractions implemented here. This implementation is based on a
|
||||
// condition variable. This implementation tracks active goroutines:
|
||||
// the given counter is decremented for a goroutine waiting for this
|
||||
// varible to be set and incremented when such a goroutine is
|
||||
// unblocked.
|
||||
type promisoid struct {
|
||||
lock sync.Locker
|
||||
cond sync.Cond
|
||||
activeCounter counter.GoRoutineCounter // counter of active goroutines
|
||||
waitingCount int // number of goroutines idle due to this being unset
|
||||
isSet bool
|
||||
value interface{}
|
||||
}
|
||||
|
||||
func (pr *promisoid) Get() interface{} {
|
||||
pr.lock.Lock()
|
||||
defer pr.lock.Unlock()
|
||||
return pr.GetLocked()
|
||||
}
|
||||
|
||||
func (pr *promisoid) GetLocked() interface{} {
|
||||
if !pr.isSet {
|
||||
pr.waitingCount++
|
||||
pr.activeCounter.Add(-1)
|
||||
pr.cond.Wait()
|
||||
}
|
||||
return pr.value
|
||||
}
|
||||
|
||||
func (pr *promisoid) IsSet() bool {
|
||||
pr.lock.Lock()
|
||||
defer pr.lock.Unlock()
|
||||
return pr.IsSetLocked()
|
||||
}
|
||||
|
||||
func (pr *promisoid) IsSetLocked() bool {
|
||||
return pr.isSet
|
||||
}
|
||||
|
||||
func (pr *promisoid) SetLocked(value interface{}) {
|
||||
pr.isSet = true
|
||||
pr.value = value
|
||||
if pr.waitingCount > 0 {
|
||||
pr.activeCounter.Add(pr.waitingCount)
|
||||
pr.waitingCount = 0
|
||||
pr.cond.Broadcast()
|
||||
}
|
||||
}
|
||||
|
||||
type writeOnce struct {
|
||||
promisoid
|
||||
}
|
||||
|
||||
var _ promise.LockingWriteOnce = &writeOnce{}
|
||||
|
||||
// NewWriteOnce makes a new promise.LockingWriteOnce
|
||||
func NewWriteOnce(lock sync.Locker, activeCounter counter.GoRoutineCounter) promise.LockingWriteOnce {
|
||||
return &writeOnce{promisoid{
|
||||
lock: lock,
|
||||
cond: *sync.NewCond(lock),
|
||||
activeCounter: activeCounter,
|
||||
}}
|
||||
}
|
||||
|
||||
func (wr *writeOnce) Set(value interface{}) bool {
|
||||
wr.lock.Lock()
|
||||
defer wr.lock.Unlock()
|
||||
return wr.SetLocked(value)
|
||||
}
|
||||
|
||||
func (wr *writeOnce) SetLocked(value interface{}) bool {
|
||||
if wr.isSet {
|
||||
return false
|
||||
}
|
||||
wr.promisoid.SetLocked(value)
|
||||
return true
|
||||
}
|
||||
|
||||
type writeMultiple struct {
|
||||
promisoid
|
||||
}
|
||||
|
||||
var _ promise.LockingWriteMultiple = &writeMultiple{}
|
||||
|
||||
// NewWriteMultiple makes a new promise.LockingWriteMultiple
|
||||
func NewWriteMultiple(lock sync.Locker, activeCounter counter.GoRoutineCounter) promise.LockingWriteMultiple {
|
||||
return &writeMultiple{promisoid{
|
||||
lock: lock,
|
||||
cond: *sync.NewCond(lock),
|
||||
activeCounter: activeCounter,
|
||||
}}
|
||||
}
|
||||
|
||||
func (wr *writeMultiple) Set(value interface{}) {
|
||||
wr.lock.Lock()
|
||||
defer wr.lock.Unlock()
|
||||
wr.SetLocked(value)
|
||||
}
|
||||
70
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go
generated
vendored
Normal file
70
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright 2019 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 promise
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// promise implements the WriteOnce interface.
|
||||
type promise struct {
|
||||
doneCh <-chan struct{}
|
||||
doneVal interface{}
|
||||
setCh chan struct{}
|
||||
onceler sync.Once
|
||||
value interface{}
|
||||
}
|
||||
|
||||
var _ WriteOnce = &promise{}
|
||||
|
||||
// NewWriteOnce makes a new thread-safe WriteOnce.
|
||||
//
|
||||
// If `initial` is non-nil then that value is Set at creation time.
|
||||
//
|
||||
// If a `Get` is waiting soon after `doneCh` becomes selectable (which
|
||||
// never happens for the nil channel) then `Set(doneVal)` effectively
|
||||
// happens at that time.
|
||||
func NewWriteOnce(initial interface{}, doneCh <-chan struct{}, doneVal interface{}) WriteOnce {
|
||||
p := &promise{
|
||||
doneCh: doneCh,
|
||||
doneVal: doneVal,
|
||||
setCh: make(chan struct{}),
|
||||
}
|
||||
if initial != nil {
|
||||
p.Set(initial)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *promise) Get() interface{} {
|
||||
select {
|
||||
case <-p.setCh:
|
||||
case <-p.doneCh:
|
||||
p.Set(p.doneVal)
|
||||
}
|
||||
return p.value
|
||||
}
|
||||
|
||||
func (p *promise) Set(value interface{}) bool {
|
||||
var ans bool
|
||||
p.onceler.Do(func() {
|
||||
p.value = value
|
||||
close(p.setCh)
|
||||
ans = true
|
||||
})
|
||||
return ans
|
||||
}
|
||||
7
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go
generated
vendored
7
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go
generated
vendored
@@ -52,12 +52,12 @@ limitations under the License.
|
||||
// limit. In the original paper, the partial derivative of R(t) with
|
||||
// respect to t is
|
||||
//
|
||||
// 1 / NEQ(t) .
|
||||
// 1 / NEQ(t) .
|
||||
//
|
||||
// To generalize from transmitting one packet at a time to executing C
|
||||
// requests at a time, that derivative becomes
|
||||
//
|
||||
// C / NEQ(t) .
|
||||
// C / NEQ(t) .
|
||||
//
|
||||
// However, sometimes there are fewer than C requests available to
|
||||
// execute. For a given queue "q", let us also write "reqs(q, t)" for
|
||||
@@ -70,7 +70,7 @@ limitations under the License.
|
||||
// for server requests: at a particular time t, the partial derivative
|
||||
// of R(t) with respect to t is
|
||||
//
|
||||
// min( C, sum[over q] reqs(q, t) ) / NEQ(t) .
|
||||
// min( C, sum[over q] reqs(q, t) ) / NEQ(t) .
|
||||
//
|
||||
// In terms of the implementation outline, this is the rate at which
|
||||
// virtual time is advancing at time t (in virtual nanoseconds per
|
||||
@@ -116,5 +116,4 @@ limitations under the License.
|
||||
// queue’s virtual start time is advanced by G. When a request
|
||||
// finishes being served, and the actual service time was S, the
|
||||
// queue’s virtual start time is decremented by G - S.
|
||||
//
|
||||
package queueset
|
||||
|
||||
156
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go
generated
vendored
Normal file
156
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Copyright 2021 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 queueset
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
)
|
||||
|
||||
// removeFromFIFOFunc removes a designated element from the list
|
||||
// if that element is in the list.
|
||||
// The complexity of the runtime cost is O(1).
|
||||
// The returned value is the element removed, if indeed one was removed,
|
||||
// otherwise `nil`.
|
||||
type removeFromFIFOFunc func() *request
|
||||
|
||||
// walkFunc is called for each request in the list in the
|
||||
// oldest -> newest order.
|
||||
// ok: if walkFunc returns false then the iteration stops immediately.
|
||||
// walkFunc may remove the given request from the fifo,
|
||||
// but may not mutate the fifo in any othe way.
|
||||
type walkFunc func(*request) (ok bool)
|
||||
|
||||
// Internal interface to abstract out the implementation details
|
||||
// of the underlying list used to maintain the requests.
|
||||
//
|
||||
// Note that a fifo, including the removeFromFIFOFuncs returned from Enqueue,
|
||||
// is not safe for concurrent use by multiple goroutines.
|
||||
type fifo interface {
|
||||
// Enqueue enqueues the specified request into the list and
|
||||
// returns a removeFromFIFOFunc function that can be used to remove the
|
||||
// request from the list
|
||||
Enqueue(*request) removeFromFIFOFunc
|
||||
|
||||
// Dequeue pulls out the oldest request from the list.
|
||||
Dequeue() (*request, bool)
|
||||
|
||||
// Peek returns the oldest request without removing it.
|
||||
Peek() (*request, bool)
|
||||
|
||||
// Length returns the number of requests in the list.
|
||||
Length() int
|
||||
|
||||
// QueueSum returns the sum of initial seats, final seats, and
|
||||
// additional latency aggregated from all requests in this queue.
|
||||
QueueSum() queueSum
|
||||
|
||||
// Walk iterates through the list in order of oldest -> newest
|
||||
// and executes the specified walkFunc for each request in that order.
|
||||
//
|
||||
// if the specified walkFunc returns false the Walk function
|
||||
// stops the walk an returns immediately.
|
||||
Walk(walkFunc)
|
||||
}
|
||||
|
||||
// the FIFO list implementation is not safe for concurrent use by multiple
|
||||
// goroutines.
|
||||
type requestFIFO struct {
|
||||
*list.List
|
||||
|
||||
sum queueSum
|
||||
}
|
||||
|
||||
func newRequestFIFO() fifo {
|
||||
return &requestFIFO{
|
||||
List: list.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *requestFIFO) Length() int {
|
||||
return l.Len()
|
||||
}
|
||||
|
||||
func (l *requestFIFO) QueueSum() queueSum {
|
||||
return l.sum
|
||||
}
|
||||
|
||||
func (l *requestFIFO) Enqueue(req *request) removeFromFIFOFunc {
|
||||
e := l.PushBack(req)
|
||||
addToQueueSum(&l.sum, req)
|
||||
|
||||
return func() *request {
|
||||
if e.Value == nil {
|
||||
return nil
|
||||
}
|
||||
l.Remove(e)
|
||||
e.Value = nil
|
||||
deductFromQueueSum(&l.sum, req)
|
||||
return req
|
||||
}
|
||||
}
|
||||
|
||||
func (l *requestFIFO) Dequeue() (*request, bool) {
|
||||
return l.getFirst(true)
|
||||
}
|
||||
|
||||
func (l *requestFIFO) Peek() (*request, bool) {
|
||||
return l.getFirst(false)
|
||||
}
|
||||
|
||||
func (l *requestFIFO) getFirst(remove bool) (*request, bool) {
|
||||
e := l.Front()
|
||||
if e == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if remove {
|
||||
defer func() {
|
||||
l.Remove(e)
|
||||
e.Value = nil
|
||||
}()
|
||||
}
|
||||
|
||||
request, ok := e.Value.(*request)
|
||||
if remove && ok {
|
||||
deductFromQueueSum(&l.sum, request)
|
||||
}
|
||||
return request, ok
|
||||
}
|
||||
|
||||
func (l *requestFIFO) Walk(f walkFunc) {
|
||||
var next *list.Element
|
||||
for current := l.Front(); current != nil; current = next {
|
||||
next = current.Next() // f is allowed to remove current
|
||||
if r, ok := current.Value.(*request); ok {
|
||||
if !f(r) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addToQueueSum(sum *queueSum, req *request) {
|
||||
sum.InitialSeatsSum += req.InitialSeats()
|
||||
sum.MaxSeatsSum += req.MaxSeats()
|
||||
sum.TotalWorkSum += req.totalWork()
|
||||
}
|
||||
|
||||
func deductFromQueueSum(sum *queueSum, req *request) {
|
||||
sum.InitialSeatsSum -= req.InitialSeats()
|
||||
sum.MaxSeatsSum -= req.MaxSeats()
|
||||
sum.TotalWorkSum -= req.totalWork()
|
||||
}
|
||||
769
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go
generated
vendored
769
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go
generated
vendored
File diff suppressed because it is too large
Load Diff
133
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go
generated
vendored
133
vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go
generated
vendored
@@ -24,10 +24,11 @@ import (
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/debug"
|
||||
fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing"
|
||||
"k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise"
|
||||
fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request"
|
||||
)
|
||||
|
||||
// request is a temporary container for "requests" with additional
|
||||
// tracking fields required for the functionality FQScheduler
|
||||
// tracking fields required for QueueSet functionality.
|
||||
type request struct {
|
||||
ctx context.Context
|
||||
|
||||
@@ -40,15 +41,17 @@ type request struct {
|
||||
// a queue.
|
||||
queue *queue
|
||||
|
||||
// startTime is the real time when the request began executing
|
||||
startTime time.Time
|
||||
// estimated amount of work of the request
|
||||
workEstimate completedWorkEstimate
|
||||
|
||||
// decision gets set to a `requestDecision` indicating what to do
|
||||
// with this request. It gets set exactly once, when the request
|
||||
// is removed from its queue. The value will be decisionReject,
|
||||
// decisionCancel, or decisionExecute; decisionTryAnother never
|
||||
// appears here.
|
||||
decision promise.LockingWriteOnce
|
||||
// decisionCancel, or decisionExecute.
|
||||
//
|
||||
// decision.Set is called with the queueSet locked.
|
||||
// decision.Get is called without the queueSet locked.
|
||||
decision promise.WriteOnce
|
||||
|
||||
// arrivalTime is the real time when the request entered this system
|
||||
arrivalTime time.Time
|
||||
@@ -57,60 +60,100 @@ type request struct {
|
||||
// log messages
|
||||
descr1, descr2 interface{}
|
||||
|
||||
queueNoteFn fq.QueueNoteFn
|
||||
|
||||
// The preceding fields are filled in at creation and not modified since;
|
||||
// the following fields may be modified later and must only be accessed while
|
||||
// holding the queueSet's lock.
|
||||
|
||||
// Removes this request from its queue. If the request is not put into a
|
||||
// a queue it will be nil.
|
||||
removeFromQueueLocked removeFromFIFOFunc
|
||||
|
||||
// arrivalR is R(arrivalTime). R is, confusingly, also called "virtual time".
|
||||
// This field is meaningful only while the request is waiting in the virtual world.
|
||||
arrivalR fcrequest.SeatSeconds
|
||||
|
||||
// startTime is the real time when the request began executing
|
||||
startTime time.Time
|
||||
|
||||
// Indicates whether client has called Request::Wait()
|
||||
waitStarted bool
|
||||
|
||||
queueNoteFn fq.QueueNoteFn
|
||||
}
|
||||
|
||||
// queue is an array of requests with additional metadata required for
|
||||
// the FQScheduler
|
||||
type completedWorkEstimate struct {
|
||||
fcrequest.WorkEstimate
|
||||
totalWork fcrequest.SeatSeconds // initial plus final work
|
||||
finalWork fcrequest.SeatSeconds // only final work
|
||||
}
|
||||
|
||||
// queue is a sequence of requests that have arrived but not yet finished
|
||||
// execution in both the real and virtual worlds.
|
||||
type queue struct {
|
||||
requests []*request
|
||||
// The requests not yet executing in the real world are stored in a FIFO list.
|
||||
requests fifo
|
||||
|
||||
// virtualStart is the virtual time (virtual seconds since process
|
||||
// startup) when the oldest request in the queue (if there is any)
|
||||
// started virtually executing
|
||||
virtualStart float64
|
||||
// nextDispatchR is the R progress meter reading at
|
||||
// which the next request will be dispatched in the virtual world.
|
||||
nextDispatchR fcrequest.SeatSeconds
|
||||
|
||||
// requestsExecuting is the count in the real world.
|
||||
requestsExecuting int
|
||||
index int
|
||||
|
||||
// index is the position of this queue among those in its queueSet.
|
||||
index int
|
||||
|
||||
// seatsInUse is the total number of "seats" currently occupied
|
||||
// by all the requests that are currently executing in this queue.
|
||||
seatsInUse int
|
||||
}
|
||||
|
||||
// Enqueue enqueues a request into the queue
|
||||
func (q *queue) Enqueue(request *request) {
|
||||
q.requests = append(q.requests, request)
|
||||
// queueSum tracks the sum of initial seats, max seats, and
|
||||
// totalWork from all requests in a given queue
|
||||
type queueSum struct {
|
||||
// InitialSeatsSum is the sum of InitialSeats
|
||||
// associated with all requests in a given queue.
|
||||
InitialSeatsSum int
|
||||
|
||||
// MaxSeatsSum is the sum of MaxSeats
|
||||
// associated with all requests in a given queue.
|
||||
MaxSeatsSum int
|
||||
|
||||
// TotalWorkSum is the sum of totalWork of the waiting requests
|
||||
TotalWorkSum fcrequest.SeatSeconds
|
||||
}
|
||||
|
||||
// Dequeue dequeues a request from the queue
|
||||
func (q *queue) Dequeue() (*request, bool) {
|
||||
if len(q.requests) == 0 {
|
||||
return nil, false
|
||||
func (req *request) totalWork() fcrequest.SeatSeconds {
|
||||
return req.workEstimate.totalWork
|
||||
}
|
||||
|
||||
func (qs *queueSet) completeWorkEstimate(we *fcrequest.WorkEstimate) completedWorkEstimate {
|
||||
finalWork := qs.computeFinalWork(we)
|
||||
return completedWorkEstimate{
|
||||
WorkEstimate: *we,
|
||||
totalWork: qs.computeInitialWork(we) + finalWork,
|
||||
finalWork: finalWork,
|
||||
}
|
||||
request := q.requests[0]
|
||||
q.requests = q.requests[1:]
|
||||
return request, true
|
||||
}
|
||||
|
||||
// GetVirtualFinish returns the expected virtual finish time of the request at
|
||||
// index J in the queue with estimated finish time G
|
||||
func (q *queue) GetVirtualFinish(J int, G float64) float64 {
|
||||
// The virtual finish time of request number J in the queue
|
||||
// (counting from J=1 for the head) is J * G + (virtual start time).
|
||||
|
||||
// counting from J=1 for the head (eg: queue.requests[0] -> J=1) - J+1
|
||||
jg := float64(J+1) * float64(G)
|
||||
return jg + q.virtualStart
|
||||
func (qs *queueSet) computeInitialWork(we *fcrequest.WorkEstimate) fcrequest.SeatSeconds {
|
||||
return fcrequest.SeatsTimesDuration(float64(we.InitialSeats), qs.estimatedServiceDuration)
|
||||
}
|
||||
|
||||
func (q *queue) dump(includeDetails bool) debug.QueueDump {
|
||||
digest := make([]debug.RequestDump, len(q.requests))
|
||||
for i, r := range q.requests {
|
||||
func (qs *queueSet) computeFinalWork(we *fcrequest.WorkEstimate) fcrequest.SeatSeconds {
|
||||
return fcrequest.SeatsTimesDuration(float64(we.FinalSeats), we.AdditionalLatency)
|
||||
}
|
||||
|
||||
func (q *queue) dumpLocked(includeDetails bool) debug.QueueDump {
|
||||
digest := make([]debug.RequestDump, q.requests.Length())
|
||||
i := 0
|
||||
q.requests.Walk(func(r *request) bool {
|
||||
// dump requests.
|
||||
digest[i].MatchedFlowSchema = r.fsName
|
||||
digest[i].FlowDistinguisher = r.flowDistinguisher
|
||||
digest[i].ArriveTime = r.arrivalTime
|
||||
digest[i].StartTime = r.startTime
|
||||
digest[i].WorkEstimate = r.workEstimate.WorkEstimate
|
||||
if includeDetails {
|
||||
userInfo, _ := genericrequest.UserFrom(r.ctx)
|
||||
digest[i].UserName = userInfo.GetName()
|
||||
@@ -119,10 +162,22 @@ func (q *queue) dump(includeDetails bool) debug.QueueDump {
|
||||
digest[i].RequestInfo = *requestInfo
|
||||
}
|
||||
}
|
||||
i++
|
||||
return true
|
||||
})
|
||||
|
||||
sum := q.requests.QueueSum()
|
||||
queueSum := debug.QueueSum{
|
||||
InitialSeatsSum: sum.InitialSeatsSum,
|
||||
MaxSeatsSum: sum.MaxSeatsSum,
|
||||
TotalWorkSum: sum.TotalWorkSum.String(),
|
||||
}
|
||||
|
||||
return debug.QueueDump{
|
||||
VirtualStart: q.virtualStart,
|
||||
NextDispatchR: q.nextDispatchR.String(),
|
||||
Requests: digest,
|
||||
ExecutingRequests: q.requestsExecuting,
|
||||
SeatsInUse: q.seatsInUse,
|
||||
QueueSum: queueSum,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user