mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Adjust final seats if they don't fit the limit
This commit is contained in:
parent
223f9be597
commit
c5a77d8a76
@ -748,6 +748,16 @@ func (qs *queueSet) findDispatchQueueLocked() *queue {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the requested final seats exceed capacity of that queue,
|
||||||
|
// we reduce them to current capacity and adjust additional latency
|
||||||
|
// to preserve the total amount of work.
|
||||||
|
if oldestReqFromMinQueue.workEstimate.FinalSeats > uint(qs.dCfg.ConcurrencyLimit) {
|
||||||
|
finalSeats := uint(qs.dCfg.ConcurrencyLimit)
|
||||||
|
additionalLatency := oldestReqFromMinQueue.workEstimate.finalWork.DurationPerSeat(float64(finalSeats))
|
||||||
|
oldestReqFromMinQueue.workEstimate.FinalSeats = finalSeats
|
||||||
|
oldestReqFromMinQueue.workEstimate.AdditionalLatency = additionalLatency
|
||||||
|
}
|
||||||
|
|
||||||
// we set the round robin indexing to start at the chose queue
|
// we set the round robin indexing to start at the chose queue
|
||||||
// for the next round. This way the non-selected queues
|
// for the next round. This way the non-selected queues
|
||||||
// win in the case that the virtual finish times are the same
|
// win in the case that the virtual finish times are the same
|
||||||
|
@ -43,3 +43,22 @@ func TestSeatSecondsString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSeatSecondsPerSeat(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
ss SeatSeconds
|
||||||
|
seats float64
|
||||||
|
expect time.Duration
|
||||||
|
}{
|
||||||
|
{ss: SeatsTimesDuration(10, time.Second), seats: 1, expect: 10 * time.Second},
|
||||||
|
{ss: SeatsTimesDuration(1, time.Second), seats: 10, expect: 100 * time.Millisecond},
|
||||||
|
{ss: SeatsTimesDuration(13, 5*time.Millisecond), seats: 5, expect: 13 * time.Millisecond},
|
||||||
|
{ss: SeatsTimesDuration(12, 0), seats: 10, expect: 0},
|
||||||
|
}
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
actualDuration := testCase.ss.DurationPerSeat(testCase.seats)
|
||||||
|
if actualDuration != testCase.expect {
|
||||||
|
t.Errorf("DurationPerSeats returned %v rather than expected %q", actualDuration, testCase.expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -81,6 +81,7 @@ type request struct {
|
|||||||
type completedWorkEstimate struct {
|
type completedWorkEstimate struct {
|
||||||
fcrequest.WorkEstimate
|
fcrequest.WorkEstimate
|
||||||
totalWork SeatSeconds // initial plus final work
|
totalWork SeatSeconds // initial plus final work
|
||||||
|
finalWork SeatSeconds // only final work
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue is an array of requests with additional metadata required for
|
// queue is an array of requests with additional metadata required for
|
||||||
@ -122,14 +123,20 @@ func (req *request) totalWork() SeatSeconds {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (qs *queueSet) completeWorkEstimate(we *fcrequest.WorkEstimate) completedWorkEstimate {
|
func (qs *queueSet) completeWorkEstimate(we *fcrequest.WorkEstimate) completedWorkEstimate {
|
||||||
|
finalWork := qs.computeFinalWork(we)
|
||||||
return completedWorkEstimate{
|
return completedWorkEstimate{
|
||||||
WorkEstimate: *we,
|
WorkEstimate: *we,
|
||||||
totalWork: qs.computeTotalWork(we),
|
totalWork: qs.computeInitialWork(we) + finalWork,
|
||||||
|
finalWork: finalWork,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *queueSet) computeTotalWork(we *fcrequest.WorkEstimate) SeatSeconds {
|
func (qs *queueSet) computeInitialWork(we *fcrequest.WorkEstimate) SeatSeconds {
|
||||||
return SeatsTimesDuration(float64(we.InitialSeats), qs.estimatedServiceDuration) + SeatsTimesDuration(float64(we.FinalSeats), we.AdditionalLatency)
|
return SeatsTimesDuration(float64(we.InitialSeats), qs.estimatedServiceDuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (qs *queueSet) computeFinalWork(we *fcrequest.WorkEstimate) SeatSeconds {
|
||||||
|
return SeatsTimesDuration(float64(we.FinalSeats), we.AdditionalLatency)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue enqueues a request into the queue and
|
// Enqueue enqueues a request into the queue and
|
||||||
@ -199,6 +206,12 @@ func (ss SeatSeconds) ToFloat() float64 {
|
|||||||
return float64(ss) / ssScale
|
return float64(ss) / ssScale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DurationPerSeat returns duration per seat.
|
||||||
|
// This division may lose precision.
|
||||||
|
func (ss SeatSeconds) DurationPerSeat(seats float64) time.Duration {
|
||||||
|
return time.Duration(float64(ss) / seats * (float64(time.Second) / ssScale))
|
||||||
|
}
|
||||||
|
|
||||||
// String converts to a string.
|
// String converts to a string.
|
||||||
// This is suitable for large as well as small values.
|
// This is suitable for large as well as small values.
|
||||||
func (ss SeatSeconds) String() string {
|
func (ss SeatSeconds) String() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user