Skip to content

Commit

Permalink
feat: factor optional "soak time" into freight availability (akuity#3100
Browse files Browse the repository at this point in the history
)

Signed-off-by: Hidde Beydals <[email protected]>
Signed-off-by: Kent Rancourt <[email protected]>
Co-authored-by: Kent Rancourt <[email protected]>
  • Loading branch information
2 people authored and fykaa committed Jan 16, 2025
1 parent 81c8723 commit 3be9fb7
Show file tree
Hide file tree
Showing 36 changed files with 3,176 additions and 1,744 deletions.
136 changes: 120 additions & 16 deletions api/v1alpha1/freight_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package v1alpha1
import (
"context"
"fmt"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)
Expand Down Expand Up @@ -85,26 +87,128 @@ func GetFreightByAlias(
return &freightList.Items[0], nil
}

// IsFreightAvailable answers whether the specified Freight is available to the
// specified Stage.
func IsFreightAvailable(stage *Stage, freight *Freight) bool {
if stage == nil || freight == nil || stage.Namespace != freight.Namespace {
return false
// ListFreightByCurrentStage returns a list of Freight resources that think
// they're currently in use by the Stage specified.
func ListFreightByCurrentStage(
ctx context.Context,
c client.Client,
stage *Stage,
) ([]Freight, error) {
freightList := FreightList{}
if err := c.List(
ctx,
&freightList,
client.InNamespace(stage.Namespace),
client.MatchingFields{"currentlyIn": stage.Name},
); err != nil {
return nil, fmt.Errorf(
"error listing Freight in namespace %q with current stage %q: %w",
stage.Namespace,
stage.Name,
err,
)
}
return freightList.Items, nil
}

// IsCurrentlyIn returns whether the Freight is currently in the specified
// Stage.
func (f *Freight) IsCurrentlyIn(stage string) bool {
// NB: This method exists for convenience. It doesn't require the caller to
// know anything about the Freight status' internal data structure.
_, in := f.Status.CurrentlyIn[stage]
return in
}

// IsVerifiedIn returns whether the Freight has been verified in the specified
// Stage.
func (f *Freight) IsVerifiedIn(stage string) bool {
// NB: This method exists for convenience. It doesn't require the caller to
// know anything about the Freight status' internal data structure.
_, verified := f.Status.VerifiedIn[stage]
return verified
}

// IsApprovedFor returns whether the Freight has been approved for the specified
// Stage.
func (f *Freight) IsApprovedFor(stage string) bool {
// NB: This method exists for convenience. It doesn't require the caller to
// know anything about the Freight status' internal data structure.
_, approved := f.Status.ApprovedFor[stage]
return approved
}

// GetLongestSoak returns the longest soak time for the Freight in the specified
// Stage if it's been verified in that Stage. If it has not, zero will be
// returned instead. If the Freight is currently in use by the specified Stage,
// the current soak time is calculated and compared to the longest completed
// soak time on record.
func (f *Freight) GetLongestSoak(stage string) time.Duration {
if _, verified := f.Status.VerifiedIn[stage]; !verified {
return 0
}
if _, approved := freight.Status.ApprovedFor[stage.Name]; approved {
return true
var longestCompleted time.Duration
if record, isVerified := f.Status.VerifiedIn[stage]; isVerified && record.LongestCompletedSoak != nil {
longestCompleted = record.LongestCompletedSoak.Duration
}
for _, req := range stage.Spec.RequestedFreight {
if freight.Origin.Equals(&req.Origin) {
if req.Sources.Direct {
return true
}
for _, source := range req.Sources.Stages {
if _, verified := freight.Status.VerifiedIn[source]; verified {
return true
var current time.Duration
if record, isCurrent := f.Status.CurrentlyIn[stage]; isCurrent {
current = time.Since(record.Since.Time)
}
return time.Duration(max(longestCompleted.Nanoseconds(), current.Nanoseconds()))
}

// AddCurrentStage updates the Freight status to reflect that the Freight is
// currently in the specified Stage.
func (f *FreightStatus) AddCurrentStage(stage string, since time.Time) {
if _, alreadyIn := f.CurrentlyIn[stage]; !alreadyIn {
if f.CurrentlyIn == nil {
f.CurrentlyIn = make(map[string]CurrentStage)
}
f.CurrentlyIn[stage] = CurrentStage{
Since: &metav1.Time{Time: since},
}
}
}

// RemoveCurrentStage updates the Freight status to reflect that the Freight is
// no longer in the specified Stage. If the Freight was verified in the
// specified Stage, the longest completed soak time will be updated if
// necessary.
func (f *FreightStatus) RemoveCurrentStage(stage string) {
if record, in := f.CurrentlyIn[stage]; in {
if _, verified := f.VerifiedIn[stage]; verified {
soak := time.Since(record.Since.Time)
if soak > f.VerifiedIn[stage].LongestCompletedSoak.Duration {
f.VerifiedIn[stage] = VerifiedStage{
LongestCompletedSoak: &metav1.Duration{Duration: soak},
}
}
}
delete(f.CurrentlyIn, stage)
}
}

// AddVerifiedStage updates the Freight status to reflect that the Freight has
// been verified in the specified Stage.
func (f *FreightStatus) AddVerifiedStage(stage string, verifiedAt time.Time) {
if _, verified := f.VerifiedIn[stage]; !verified {
record := VerifiedStage{VerifiedAt: &metav1.Time{Time: verifiedAt}}
if f.VerifiedIn == nil {
f.VerifiedIn = map[string]VerifiedStage{stage: record}
}
f.VerifiedIn[stage] = record
}
}

// AddApprovedStage updates the Freight status to reflect that the Freight has
// been approved for the specified Stage.
func (f *FreightStatus) AddApprovedStage(stage string, approvedAt time.Time) {
if _, approved := f.ApprovedFor[stage]; !approved {
record := ApprovedStage{ApprovedAt: &metav1.Time{Time: approvedAt}}
if f.ApprovedFor == nil {
f.ApprovedFor = map[string]ApprovedStage{stage: record}
}
f.ApprovedFor[stage] = record
}
return false
}
Loading

0 comments on commit 3be9fb7

Please sign in to comment.