Skip to content

Commit

Permalink
feat(analysis): add ttlStrategy on AnalysisRun for garbage collecting…
Browse files Browse the repository at this point in the history
… stale AnalysisRun automatically (#3324)

* Add ttlStrategy on AnalysisRun

Signed-off-by: Kevin Qian <[email protected]>

* Unit test coverage

Signed-off-by: Kevin Qian <[email protected]>

* Unit test 2

Signed-off-by: Kevin Qian <[email protected]>

* Regen go proto def

Signed-off-by: Kevin Qian <[email protected]>

* Doc available from 1.6 -> 1.7

Signed-off-by: Kevin Qian <[email protected]>

* TtlStrategy -> TTLStrategy

Signed-off-by: Kevin Qian <[email protected]>

---------

Signed-off-by: Kevin Qian <[email protected]>
  • Loading branch information
kevinqian-db authored Jan 30, 2024
1 parent 5e5314b commit c492b06
Show file tree
Hide file tree
Showing 13 changed files with 1,579 additions and 542 deletions.
49 changes: 48 additions & 1 deletion analysis/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"

Expand Down Expand Up @@ -40,10 +41,15 @@ type metricTask struct {
}

func (c *Controller) reconcileAnalysisRun(origRun *v1alpha1.AnalysisRun) *v1alpha1.AnalysisRun {
logger := logutil.WithAnalysisRun(origRun)
if origRun.Status.Phase.Completed() {
err := c.maybeGarbageCollectAnalysisRun(origRun, logger)
if err != nil {
// TODO(jessesuen): surface errors to controller so they can be retried
logger.Warnf("Failed to garbage collect analysis run: %v", err)
}
return origRun
}
logger := logutil.WithAnalysisRun(origRun)
run := origRun.DeepCopy()

if run.Status.MetricResults == nil {
Expand Down Expand Up @@ -108,6 +114,10 @@ func (c *Controller) reconcileAnalysisRun(origRun *v1alpha1.AnalysisRun) *v1alph
run.Status.Message = newMessage
if newStatus.Completed() {
c.recordAnalysisRunCompletionEvent(run)
if run.Status.CompletedAt == nil {
now := timeutil.MetaNow()
run.Status.CompletedAt = &now
}
}
}

Expand Down Expand Up @@ -752,3 +762,40 @@ func (c *Controller) garbageCollectMeasurements(run *v1alpha1.AnalysisRun, measu
}
return nil
}

func (c *Controller) maybeGarbageCollectAnalysisRun(run *v1alpha1.AnalysisRun, logger *log.Entry) error {
ctx := context.TODO()
if run.DeletionTimestamp != nil || !isAnalysisRunTtlExceeded(run) {
return nil
}
logger.Infof("Trying to cleanup TTL exceeded analysis run")
err := c.argoProjClientset.ArgoprojV1alpha1().AnalysisRuns(run.Namespace).Delete(ctx, run.Name, metav1.DeleteOptions{})
if err != nil && !k8serrors.IsNotFound(err) {
return err
}
return nil
}

func isAnalysisRunTtlExceeded(run *v1alpha1.AnalysisRun) bool {
// TTL only counted for completed runs with TTL strategy.
if !run.Status.Phase.Completed() || run.Spec.TTLStrategy == nil {
return false
}
// Cannot determine TTL if run has no completion time.
if run.Status.CompletedAt == nil {
return false
}
secondsCompleted := timeutil.MetaNow().Sub(run.Status.CompletedAt.Time).Seconds()
var ttlSeconds *int32
if run.Status.Phase == v1alpha1.AnalysisPhaseSuccessful && run.Spec.TTLStrategy.SecondsAfterSuccess != nil {
ttlSeconds = run.Spec.TTLStrategy.SecondsAfterSuccess
} else if run.Status.Phase == v1alpha1.AnalysisPhaseFailed && run.Spec.TTLStrategy.SecondsAfterFailure != nil {
ttlSeconds = run.Spec.TTLStrategy.SecondsAfterFailure
} else if run.Spec.TTLStrategy.SecondsAfterCompletion != nil {
ttlSeconds = run.Spec.TTLStrategy.SecondsAfterCompletion
}
if ttlSeconds == nil {
return false
}
return int32(secondsCompleted) > *ttlSeconds
}
Loading

0 comments on commit c492b06

Please sign in to comment.