Skip to content

Commit

Permalink
Set revision-timeout as an annotation in the PA
Browse files Browse the repository at this point in the history
Scale down to zero if revision timeout has gone and the revision is unreachable
  • Loading branch information
jsanin committed Jan 31, 2024
1 parent 905e516 commit 18761cb
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 23 deletions.
8 changes: 8 additions & 0 deletions pkg/apis/autoscaling/v1alpha1/pa_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ func (pa *PodAutoscaler) ProgressDeadline() (time.Duration, bool) {
return pa.annotationDuration(serving.ProgressDeadlineAnnotation)
}

func (pa *PodAutoscaler) RevisionTimeout() (time.Duration, bool) {
return pa.annotationDuration(serving.RevisionTimeoutAnnotation)
}

// InitialScale returns the initial scale on the revision if present, or false if not present.
func (pa *PodAutoscaler) InitialScale() (int32, bool) {
// The value is validated in the webhook.
Expand All @@ -187,6 +191,10 @@ func (pa *PodAutoscaler) IsReady() bool {
pas.GetCondition(PodAutoscalerConditionReady).IsTrue()
}

func (pa *PodAutoscaler) CanFailActivationOnUnreachableRevision(now time.Time, idlePeriod time.Duration) bool {
return pa.Spec.Reachability == ReachabilityUnreachable && pa.Status.CanFailActivation(now, idlePeriod)
}

// IsActive returns true if the pod autoscaler has finished scaling.
func (pas *PodAutoscalerStatus) IsActive() bool {
return pas.GetCondition(PodAutoscalerConditionActive).IsTrue()
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/serving/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ const (

// ProgressDeadlineAnnotationKey is the label key for the per revision progress deadline to set for the deployment
ProgressDeadlineAnnotationKey = GroupName + "/progress-deadline"

RevisionTimeoutAnnotationKey = GroupName + "/revision-timeout"
)

var (
Expand Down Expand Up @@ -202,4 +204,7 @@ var (
ProgressDeadlineAnnotation = kmap.KeyPriority{
ProgressDeadlineAnnotationKey,
}
RevisionTimeoutAnnotation = kmap.KeyPriority{
RevisionTimeoutAnnotationKey,
}
)
26 changes: 4 additions & 22 deletions pkg/reconciler/autoscaling/kpa/scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import (
"net/http"
"time"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"knative.dev/pkg/apis/duck"
"knative.dev/pkg/injection/clients/dynamicclient"
"knative.dev/pkg/logging"
Expand Down Expand Up @@ -189,9 +187,7 @@ func (ks *scaler) handleScaleToZero(ctx context.Context, pa *autoscalingv1alpha1
}
cfgD := cfgs.Deployment
var activationTimeout time.Duration
if revTimeout, err := ks.revisionTimeout(ctx, pa); err == nil && revTimeout > 0 {
activationTimeout = time.Duration(revTimeout) * time.Second
} else if progressDeadline, ok := pa.ProgressDeadline(); ok {
if progressDeadline, ok := pa.ProgressDeadline(); ok {
activationTimeout = progressDeadline + activationTimeoutBuffer
} else {
activationTimeout = cfgD.ProgressDeadline + activationTimeoutBuffer
Expand All @@ -205,6 +201,9 @@ func (ks *scaler) handleScaleToZero(ctx context.Context, pa *autoscalingv1alpha1
if pa.Status.CanFailActivation(now, activationTimeout) {
logger.Info("Activation has timed out after ", activationTimeout)
return desiredScale, true
} else if revTimeout, ok := pa.RevisionTimeout(); ok && pa.CanFailActivationOnUnreachableRevision(now, revTimeout) {
logger.Info("Activation has timed out after revision-timeout ", revTimeout)
return desiredScale, true
}
ks.enqueueCB(pa, activationTimeout)
return scaleUnknown, false
Expand Down Expand Up @@ -373,20 +372,3 @@ func (ks *scaler) scale(ctx context.Context, pa *autoscalingv1alpha1.PodAutoscal
logger.Infof("Scaling from %d to %d", currentScale, desiredScale)
return desiredScale, ks.applyScale(ctx, pa, desiredScale, ps)
}
func (ks *scaler) revisionTimeout(ctx context.Context, pa *autoscalingv1alpha1.PodAutoscaler) (int64, error) {
gvr := schema.GroupVersionResource{
Group: "serving.knative.dev",
Version: "v1",
Resource: "revisions",
}
uRevision, err := ks.dynamicClient.Resource(gvr).Namespace(pa.Namespace).Get(ctx, pa.Name, metav1.GetOptions{})
if err == nil {
var timeoutSeconds interface{}
var found bool
timeoutSeconds, found, err = unstructured.NestedFieldNoCopy(uRevision.Object, "spec", "timeoutSeconds")
if err == nil && found {
return timeoutSeconds.(int64), nil
}
}
return -1, err
}
6 changes: 5 additions & 1 deletion pkg/reconciler/revision/resources/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ package resources
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"knative.dev/pkg/kmap"
"knative.dev/pkg/kmeta"
"knative.dev/serving/pkg/apis/serving"
v1 "knative.dev/serving/pkg/apis/serving/v1"
"strconv"
)

var (
Expand Down Expand Up @@ -56,7 +58,9 @@ func makeLabels(revision *v1.Revision) map[string]string {
}

func makeAnnotations(revision *v1.Revision) map[string]string {
return kmeta.FilterMap(revision.GetAnnotations(), excludeAnnotations.Has)
annotations := kmap.Filter(revision.GetAnnotations(), excludeAnnotations.Has)
annotations[serving.RevisionTimeoutAnnotation.Key()] = strconv.FormatInt(*revision.Spec.TimeoutSeconds, 10) + "s"
return annotations
}

// makeSelector constructs the Selector we will apply to K8s resources.
Expand Down

0 comments on commit 18761cb

Please sign in to comment.