Skip to content

Commit d2a2644

Browse files
authored
Merge pull request #17 from Fedosin/small-cleanup
Remove unused fields
2 parents 0cfb0b8 + e19d687 commit d2a2644

File tree

12 files changed

+7
-313
lines changed

12 files changed

+7
-313
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ This library extracts the battle-tested autoscaling algorithms from Knative Serv
1414
- **Configurable scale-up/down rates** to prevent flapping
1515
- **Scale-to-zero capabilities** with grace periods
1616
- **Support for multiple metrics**
17-
- **Burst capacity calculations** for traffic absorption
1817

1918
## Installation
2019

algorithm/algorithm_test.go

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,13 @@ func defaultConfig() api.AutoscalerConfig {
4242
MaxScaleUpRate: 1000.0,
4343
MaxScaleDownRate: 2.0,
4444
TargetValue: 100.0,
45-
TotalValue: 1000.0,
46-
TargetBurstCapacity: 211.0,
4745
PanicThreshold: 2.0, // 200%
4846
PanicWindowPercentage: 10.0,
4947
StableWindow: 60 * time.Second,
5048
ScaleDownDelay: 0,
5149
MinScale: 0,
5250
MaxScale: 0,
5351
ActivationScale: 1,
54-
Reachable: true,
5552
}
5653
}
5754

@@ -120,7 +117,6 @@ func TestSlidingWindowAutoscaler_Scale_BasicScaling(t *testing.T) {
120117
config api.AutoscalerConfig
121118
snapshot mockMetricSnapshot
122119
expectedPodCount int32
123-
expectedEBC int32 // excess burst capacity
124120
}{
125121
{
126122
name: "scale up based on stable value",
@@ -131,7 +127,6 @@ func TestSlidingWindowAutoscaler_Scale_BasicScaling(t *testing.T) {
131127
readyPodCount: 2, // start with 2 pods instead of 1
132128
},
133129
expectedPodCount: 3, // ceil(250/100)
134-
expectedEBC: 1539, // floor(2*1000 - 211 - 250)
135130
},
136131
{
137132
name: "scale down based on stable value",
@@ -142,7 +137,6 @@ func TestSlidingWindowAutoscaler_Scale_BasicScaling(t *testing.T) {
142137
readyPodCount: 5,
143138
},
144139
expectedPodCount: 2, // limited by max scale down rate (5/2.0)
145-
expectedEBC: 4739, // floor(5*1000 - 211 - 50)
146140
},
147141
{
148142
name: "respect min scale",
@@ -217,11 +211,6 @@ func TestSlidingWindowAutoscaler_Scale_BasicScaling(t *testing.T) {
217211
if recommendation.DesiredPodCount != tt.expectedPodCount {
218212
t.Errorf("expected pod count %d, got %d", tt.expectedPodCount, recommendation.DesiredPodCount)
219213
}
220-
if tt.expectedEBC != 0 && (tt.name == "scale up based on stable value" || tt.name == "scale down based on stable value") {
221-
if recommendation.ExcessBurstCapacity != tt.expectedEBC {
222-
t.Errorf("expected excess burst capacity %d, got %d", tt.expectedEBC, recommendation.ExcessBurstCapacity)
223-
}
224-
}
225214
})
226215
}
227216
}
@@ -356,27 +345,6 @@ func TestSlidingWindowAutoscaler_Scale_ScaleToZero(t *testing.T) {
356345
}
357346
}
358347

359-
func TestSlidingWindowAutoscaler_Scale_NotReachable(t *testing.T) {
360-
config := defaultConfig()
361-
config.Reachable = false
362-
363-
autoscaler := NewSlidingWindowAutoscaler(config)
364-
now := time.Now()
365-
366-
// When not reachable, maxScaleDown should be 0
367-
snapshot := &mockMetricSnapshot{
368-
stableValue: 10, // very low load
369-
panicValue: 10,
370-
readyPodCount: 5,
371-
timestamp: now,
372-
}
373-
374-
recommendation := autoscaler.Scale(snapshot, now)
375-
if recommendation.DesiredPodCount != 1 {
376-
t.Errorf("expected pod count 1 (no scale down limit when not reachable), got %d", recommendation.DesiredPodCount)
377-
}
378-
}
379-
380348
func TestSlidingWindowAutoscaler_Scale_ActivationScaleWithZeroMetrics(t *testing.T) {
381349
config := defaultConfig()
382350
config.ActivationScale = 3
@@ -420,59 +388,6 @@ func TestSlidingWindowAutoscaler_Scale_ReadyPodCountZero(t *testing.T) {
420388
}
421389
}
422390

423-
func TestCalculateExcessBurstCapacity(t *testing.T) {
424-
tests := []struct {
425-
name string
426-
readyPods int32
427-
totalValue float64
428-
targetBurstCapacity float64
429-
observedPanicValue float64
430-
expected int32
431-
}{
432-
{
433-
name: "positive excess capacity",
434-
readyPods: 5,
435-
totalValue: 1000,
436-
targetBurstCapacity: 211,
437-
observedPanicValue: 500,
438-
expected: 4289, // floor(5*1000 - 211 - 500)
439-
},
440-
{
441-
name: "negative excess capacity",
442-
readyPods: 1,
443-
totalValue: 1000,
444-
targetBurstCapacity: 211,
445-
observedPanicValue: 1000,
446-
expected: -211, // floor(1*1000 - 211 - 1000)
447-
},
448-
{
449-
name: "zero target burst capacity",
450-
readyPods: 5,
451-
totalValue: 1000,
452-
targetBurstCapacity: 0,
453-
observedPanicValue: 500,
454-
expected: 0,
455-
},
456-
{
457-
name: "negative target burst capacity (unlimited)",
458-
readyPods: 5,
459-
totalValue: 1000,
460-
targetBurstCapacity: -1,
461-
observedPanicValue: 500,
462-
expected: -1,
463-
},
464-
}
465-
466-
for _, tt := range tests {
467-
t.Run(tt.name, func(t *testing.T) {
468-
result := calculateExcessBurstCapacity(tt.readyPods, tt.totalValue, tt.targetBurstCapacity, tt.observedPanicValue)
469-
if result != tt.expected {
470-
t.Errorf("expected %d, got %d", tt.expected, result)
471-
}
472-
})
473-
}
474-
}
475-
476391
// Tests for PanicModeCalculator
477392
func TestNewPanicModeCalculator(t *testing.T) {
478393
config := defaultConfig()

algorithm/sliding_window.go

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,7 @@ func (a *SlidingWindowAutoscaler) Scale(snapshot api.MetricSnapshot, now time.Ti
9292

9393
// Calculate scale limits based on current pod count
9494
maxScaleUp := int32(math.Ceil(a.config.MaxScaleUpRate * float64(readyPodCount)))
95-
maxScaleDown := int32(0)
96-
if a.config.Reachable {
97-
maxScaleDown = int32(math.Floor(float64(readyPodCount) / a.config.MaxScaleDownRate))
98-
}
95+
maxScaleDown := int32(math.Floor(float64(readyPodCount) / a.config.MaxScaleDownRate))
9996

10097
// raw pod counts calculated directly from metrics, prior to applying any rate limits.
10198
var rawStablePodCount, rawPanicPodCount int32
@@ -162,7 +159,7 @@ func (a *SlidingWindowAutoscaler) Scale(snapshot api.MetricSnapshot, now time.Ti
162159
}
163160

164161
// Apply scale-down delay if configured
165-
if a.config.Reachable && a.maxTimeWindow != nil {
162+
if a.maxTimeWindow != nil {
166163
a.maxTimeWindow.Record(now, desiredPodCount)
167164
desiredPodCount = a.maxTimeWindow.Current()
168165
}
@@ -175,17 +172,8 @@ func (a *SlidingWindowAutoscaler) Scale(snapshot api.MetricSnapshot, now time.Ti
175172
desiredPodCount = a.config.MaxScale
176173
}
177174

178-
// Calculate excess burst capacity
179-
excessBurstCapacity := calculateExcessBurstCapacity(
180-
snapshot.ReadyPodCount(),
181-
a.config.TotalValue,
182-
a.config.TargetBurstCapacity,
183-
observedPanicValue,
184-
)
185-
186175
return api.ScaleRecommendation{
187176
DesiredPodCount: desiredPodCount,
188-
ExcessBurstCapacity: excessBurstCapacity,
189177
ScaleValid: true,
190178
InPanicMode: inPanicMode,
191179
}
@@ -212,19 +200,3 @@ func (a *SlidingWindowAutoscaler) GetConfig() api.AutoscalerConfig {
212200
defer a.mu.RUnlock()
213201
return a.config
214202
}
215-
216-
// calculateExcessBurstCapacity computes the excess burst capacity.
217-
// A negative value means the deployment doesn't have enough capacity
218-
// to handle the target burst capacity.
219-
func calculateExcessBurstCapacity(readyPods int32, totalValue, targetBurstCapacity, observedPanicValue float64) int32 {
220-
if targetBurstCapacity == 0 {
221-
return 0
222-
}
223-
if targetBurstCapacity < 0 {
224-
return -1 // Unlimited
225-
}
226-
227-
totalCapacity := float64(readyPods) * totalValue
228-
excessBurstCapacity := math.Floor(totalCapacity - targetBurstCapacity - observedPanicValue)
229-
return int32(excessBurstCapacity)
230-
}

api/types.go

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,9 @@ type AutoscalerConfig struct {
3434
MaxScaleDownRate float64
3535

3636
// TargetValue is the desired value of the scaling metric per pod that we aim to maintain.
37-
// This must be less than or equal to TotalValue. Default is 100.0.
37+
// Default is 100.0.
3838
TargetValue float64
3939

40-
// TotalValue is the total capacity of the scaling metric that a pod can handle.
41-
// Default is 1000.0.
42-
TotalValue float64
43-
44-
// TargetBurstCapacity is the desired burst capacity to maintain without queuing.
45-
// If negative, it means unlimited burst capacity. Default is 211.0.
46-
TargetBurstCapacity float64
47-
4840
// PanicThreshold is the threshold for entering panic mode, expressed as a
4941
// percentage of desired pod count. If the observed load over the panic window
5042
// exceeds this percentage of the current pod count capacity, panic mode is triggered.
@@ -78,11 +70,6 @@ type AutoscalerConfig struct {
7870
// ScaleToZeroGracePeriod is the time to wait before scaling to zero
7971
// after the service becomes idle. Default is 30s.
8072
ScaleToZeroGracePeriod time.Duration
81-
82-
// Reachable indicates whether the service is reachable (has active traffic).
83-
// This affects scale-down behavior. Default is true.
84-
// Deprecated: Used in legacy scaling mode to support Knative Serving revisions.
85-
Reachable bool
8673
}
8774

8875
// Metrics represents collected metrics.
@@ -99,11 +86,6 @@ type ScaleRecommendation struct {
9986
// DesiredPodCount is the recommended number of pods.
10087
DesiredPodCount int32
10188

102-
// ExcessBurstCapacity is the difference between spare capacity and
103-
// configured target burst capacity. Negative values indicate insufficient
104-
// capacity for the desired burst level.
105-
ExcessBurstCapacity int32
106-
10789
// ScaleValid indicates whether the recommendation is valid.
10890
// False if insufficient data was available.
10991
ScaleValid bool

config/config.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ const (
3434
// Default values
3535
defaultMaxScaleUpRate = 1000.0
3636
defaultMaxScaleDownRate = 2.0
37-
defaultTargetBurstCapacity = 211.0
3837
defaultPanicWindowPercentage = 10.0
3938
defaultPanicThresholdPercentage = 200.0
4039
defaultStableWindow = 60 * time.Second
@@ -95,12 +94,6 @@ func Load() (*api.AutoscalerConfig, error) {
9594
targetValue, err := getEnvFloat("TARGET_VALUE", 0.0)
9695
errs.add(err)
9796

98-
totalValue, err := getEnvFloat("TOTAL_VALUE", 0.0)
99-
errs.add(err)
100-
101-
targetBurstCapacity, err := getEnvFloat("TARGET_BURST_CAPACITY", defaultTargetBurstCapacity)
102-
errs.add(err)
103-
10497
panicThreshold, err := getEnvFloat("PANIC_THRESHOLD_PERCENTAGE", defaultPanicThresholdPercentage)
10598
errs.add(err)
10699

@@ -131,8 +124,6 @@ func Load() (*api.AutoscalerConfig, error) {
131124
MaxScaleUpRate: maxScaleUpRate,
132125
MaxScaleDownRate: maxScaleDownRate,
133126
TargetValue: targetValue,
134-
TotalValue: totalValue,
135-
TargetBurstCapacity: targetBurstCapacity,
136127
PanicThreshold: panicThreshold,
137128
PanicWindowPercentage: panicWindowPercentage,
138129
StableWindow: stableWindow,
@@ -167,12 +158,6 @@ func LoadFromMap(data map[string]string) (*api.AutoscalerConfig, error) {
167158
targetValue, err := parseFloat(data["target-value"], 0.0)
168159
errs.add(err)
169160

170-
totalValue, err := parseFloat(data["total-value"], 0.0)
171-
errs.add(err)
172-
173-
targetBurstCapacity, err := parseFloat(data["target-burst-capacity"], defaultTargetBurstCapacity)
174-
errs.add(err)
175-
176161
panicThreshold, err := parseFloat(data["panic-threshold-percentage"], defaultPanicThresholdPercentage)
177162
errs.add(err)
178163

@@ -203,8 +188,6 @@ func LoadFromMap(data map[string]string) (*api.AutoscalerConfig, error) {
203188
MaxScaleUpRate: maxScaleUpRate,
204189
MaxScaleDownRate: maxScaleDownRate,
205190
TargetValue: targetValue,
206-
TotalValue: totalValue,
207-
TargetBurstCapacity: targetBurstCapacity,
208191
PanicThreshold: panicThreshold,
209192
PanicWindowPercentage: panicWindowPercentage,
210193
StableWindow: stableWindow,
@@ -239,21 +222,10 @@ func validate(cfg *api.AutoscalerConfig) error {
239222
errs.add(fmt.Errorf("scale-down-delay = %v, must be specified with at most second precision", cfg.ScaleDownDelay))
240223
}
241224

242-
// Validate target burst capacity
243-
if cfg.TargetBurstCapacity < 0 && cfg.TargetBurstCapacity != -1 {
244-
errs.add(fmt.Errorf("target-burst-capacity must be either non-negative or -1 (for unlimited), was: %f", cfg.TargetBurstCapacity))
245-
}
246-
247225
// Validate target values
248-
if cfg.TargetValue > cfg.TotalValue {
249-
errs.add(fmt.Errorf("target-value = %v, must be less than or equal to total-value = %v", cfg.TargetValue, cfg.TotalValue))
250-
}
251226
if cfg.TargetValue <= 0 {
252227
errs.add(fmt.Errorf("target-value = %v, must be positive", cfg.TargetValue))
253228
}
254-
if cfg.TotalValue <= 0 {
255-
errs.add(fmt.Errorf("total-value = %v, must be positive", cfg.TotalValue))
256-
}
257229

258230
// Validate scale rates
259231
if cfg.MaxScaleUpRate <= 1.0 {

0 commit comments

Comments
 (0)