Skip to content

Commit

Permalink
add InitialCooldownPeriod for ScaledObjects (kedacore#5478)
Browse files Browse the repository at this point in the history
Signed-off-by: xrwang <68765051+xrwang8@users.noreply.github.com>
Signed-off-by: wangxingrui <xrwang8@gmail.com>
Co-authored-by: Jorge Turrado Ferrero <Jorge_turrado@hotmail.es>
Co-authored-by: Zbynek Roubalik <zroubalik@gmail.com>
  • Loading branch information
3 people committed Apr 12, 2024
1 parent adfe867 commit 80806a7
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio

- **General**: Provide capability to filter CloudEvents ([#3533](https://github.com/kedacore/keda/issues/3533))
- **NATS Scaler**: Add TLS authentication ([#2296](https://github.com/kedacore/keda/issues/2296))
- **ScaledObject**: Ability to specify `initialCooldownPeriod` ([#5008](https://github.com/kedacore/keda/issues/5008))



#### Experimental

Expand Down
2 changes: 2 additions & 0 deletions apis/keda/v1alpha1/scaledobject_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type ScaledObjectSpec struct {
Triggers []ScaleTriggers `json:"triggers"`
// +optional
Fallback *Fallback `json:"fallback,omitempty"`
// +optional
InitialCooldownPeriod int32 `json:"initialCooldownPeriod,omitempty"`
}

// Fallback is the spec for fallback options
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/keda.sh_scaledobjects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ spec:
idleReplicaCount:
format: int32
type: integer
initialCooldownPeriod:
format: int32
type: integer
maxReplicaCount:
format: int32
type: integer
Expand Down
12 changes: 9 additions & 3 deletions pkg/scaling/executor/scale_scaledobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,18 @@ func (e *scaleExecutor) scaleToZeroOrIdle(ctx context.Context, logger logr.Logge
cooldownPeriod = time.Second * time.Duration(defaultCooldownPeriod)
}

initialCooldownPeriod := time.Second * time.Duration(scaledObject.Spec.InitialCooldownPeriod)

// If the ScaledObject was just created,CreationTimestamp is zero, set the CreationTimestamp to now
if scaledObject.ObjectMeta.CreationTimestamp.IsZero() {
scaledObject.ObjectMeta.CreationTimestamp = metav1.NewTime(time.Now())
}

// LastActiveTime can be nil if the ScaleTarget was scaled outside of KEDA.
// In this case we will ignore the cooldown period and scale it down
if scaledObject.Status.LastActiveTime == nil ||
scaledObject.Status.LastActiveTime.Add(cooldownPeriod).Before(time.Now()) {
if (scaledObject.Status.LastActiveTime == nil && scaledObject.ObjectMeta.CreationTimestamp.Add(initialCooldownPeriod).Before(time.Now())) || (scaledObject.Status.LastActiveTime != nil &&
scaledObject.Status.LastActiveTime.Add(cooldownPeriod).Before(time.Now())) {
// or last time a trigger was active was > cooldown period, so scale in.

idleValue, scaleToReplicas := getIdleOrMinimumReplicaCount(scaledObject)

currentReplicas, err := e.updateScaleOnScaleTarget(ctx, scaledObject, scale, scaleToReplicas)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//go:build e2e
// +build e2e

package initial_delay_cooldownperiod_test

import (
"fmt"
"strconv"
"testing"
"time"

"github.com/stretchr/testify/assert"

. "github.com/kedacore/keda/v2/tests/helper"
)

const (
testName = "initial-delay-cooldownperiod-test"
)

var (
testNamespace = fmt.Sprintf("%s-ns", testName)
deploymentName = fmt.Sprintf("%s-deployment", testName)
scaledObjectName = fmt.Sprintf("%s-so", testName)

now = time.Now().Local()
start = (now.Minute() + 10) % 60
end = (start + 1) % 60
)

type templateData struct {
TestNamespace string
DeploymentName string
ScaledObjectName string
StartMin string
EndMin string
}

const (
deploymentTemplate = `
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.DeploymentName}}
namespace: {{.TestNamespace}}
labels:
deploy: {{.DeploymentName}}
spec:
replicas: 1
selector:
matchLabels:
pod: {{.DeploymentName}}
template:
metadata:
labels:
pod: {{.DeploymentName}}
spec:
containers:
- name: nginx
image: 'nginxinc/nginx-unprivileged'
`

scaledObjectTemplate = `
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: {{.ScaledObjectName}}
namespace: {{.TestNamespace}}
spec:
scaleTargetRef:
name: {{.DeploymentName}}
cooldownPeriod: 5
minReplicaCount: 0
initialCooldownPeriod: 120
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 15
triggers:
- type: cron
metadata:
timezone: Etc/UTC
start: {{.StartMin}} * * * *
end: {{.EndMin}} * * * *
desiredReplicas: '0'
`
)

func TestScaler(t *testing.T) {
// setup
t.Log("--- setting up ---")

// Create kubernetes resources
kc := GetKubernetesClient(t)
data, templates := getTemplateData()

CreateKubernetesResources(t, kc, testNamespace, data, templates)
assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, 1, 60, 1),
"replica count should be %d after 1 minute", 1)
t.Log("--- Waiting for some time to ensure deployment replica count doesn't change ---")
AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, 1, 90)
t.Log("--- scale to 0 replicas ---")
assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, 0, 120, 1),
"replica count should be %d after 2 minute", 0) // Assert that the workload is scaled to zero after the initial cooldown period

DeleteKubernetesResources(t, testNamespace, data, templates)
}
func getTemplateData() (templateData, []Template) {
return templateData{
TestNamespace: testNamespace,
DeploymentName: deploymentName,
ScaledObjectName: scaledObjectName,
StartMin: strconv.Itoa(start),
EndMin: strconv.Itoa(end),
}, []Template{
{Name: "deploymentTemplate", Config: deploymentTemplate},
{Name: "scaledObjectTemplate", Config: scaledObjectTemplate},
}
}

0 comments on commit 80806a7

Please sign in to comment.