Workflow lifecycle events + resource instance duration tracking
- Add WorkflowLifecycleEvent + StepMetric to tools/workflow_lifecycle.go - Add WORKFLOW_STARTED_EVENT, WORKFLOW_STEP_DONE_EVENT, WORKFLOW_DONE_EVENT NATS methods - ResourceInstance.UpdateAverageDuration for AverageDurationS running average - Support Steps recap in WORKFLOW_DONE_EVENT for catch-up by oc-scheduler/oc-catalog Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,7 +66,7 @@ func (r *AbstractResource) CanDelete() bool {
|
||||
type AbstractInstanciatedResource[T ResourceInstanceITF] struct {
|
||||
AbstractResource // AbstractResource contains the basic fields of an object (id, name)
|
||||
|
||||
Instances []T `json:"instances,omitempty" bson:"instances,omitempty"` // Bill is the bill of the resource // Bill is the bill of the resource
|
||||
Instances []T `json:"instances,omitempty" bson:"instances,omitempty"`
|
||||
}
|
||||
|
||||
func (abs *AbstractInstanciatedResource[T]) AddInstances(instance ResourceInstanceITF) {
|
||||
@@ -109,17 +109,26 @@ func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.Data
|
||||
if selectedBookingModeIndex != nil && abs.AllowedBookingModes[booking.BookingMode(*selectedBookingModeIndex)] != nil {
|
||||
variations = append(variations, abs.AllowedBookingModes[booking.BookingMode(*selectedBookingModeIndex)])
|
||||
}
|
||||
// Seed the booking configuration with the instance's historical average duration
|
||||
// so GetExplicitDurationInS() returns a realistic default out of the box.
|
||||
var bc *BookingConfiguration
|
||||
if inst != nil {
|
||||
if avg := inst.GetAverageDurationS(); avg > 0 {
|
||||
bc = &BookingConfiguration{ExplicitBookingDurationS: avg}
|
||||
}
|
||||
}
|
||||
return &PricedResource{
|
||||
Name: abs.Name,
|
||||
Logo: abs.Logo,
|
||||
ResourceID: abs.UUID,
|
||||
InstanceID: inst.GetID(),
|
||||
ResourceType: t,
|
||||
Quantity: 1,
|
||||
InstancesRefs: instances,
|
||||
SelectedPricing: profile,
|
||||
Variations: variations,
|
||||
CreatorID: abs.CreatorID,
|
||||
Name: abs.Name,
|
||||
Logo: abs.Logo,
|
||||
ResourceID: abs.UUID,
|
||||
InstanceID: inst.GetID(),
|
||||
ResourceType: t,
|
||||
Quantity: 1,
|
||||
InstancesRefs: instances,
|
||||
SelectedPricing: profile,
|
||||
Variations: variations,
|
||||
CreatorID: abs.CreatorID,
|
||||
BookingConfiguration: bc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -196,6 +205,9 @@ type ResourceInstance[T ResourcePartnerITF] struct {
|
||||
Outputs []models.Param `json:"outputs,omitempty" bson:"outputs,omitempty"`
|
||||
|
||||
Partnerships []T `json:"partnerships,omitempty" bson:"partnerships,omitempty"`
|
||||
|
||||
AverageDurationS float64 `json:"average_duration_s,omitempty" bson:"average_duration_s,omitempty"`
|
||||
AverageDurationSamples int `json:"average_duration_samples,omitempty" bson:"average_duration_samples,omitempty"`
|
||||
}
|
||||
|
||||
// TODO should kicks all selection
|
||||
@@ -285,6 +297,17 @@ func (ri *ResourceInstance[T]) ClearPeerGroups() {
|
||||
}
|
||||
}
|
||||
|
||||
func (ri *ResourceInstance[T]) GetAverageDurationS() float64 {
|
||||
return ri.AverageDurationS
|
||||
}
|
||||
|
||||
func (ri *ResourceInstance[T]) UpdateAverageDuration(actualS float64) {
|
||||
buffered := actualS * 1.20
|
||||
n := float64(ri.AverageDurationSamples)
|
||||
ri.AverageDurationS = (ri.AverageDurationS*n + buffered) / (n + 1)
|
||||
ri.AverageDurationSamples++
|
||||
}
|
||||
|
||||
type ResourcePartnerShip[T pricing.PricingProfileITF] struct {
|
||||
Namespace string `json:"namespace" bson:"namespace" default:"default-namespace"`
|
||||
PeerGroups map[string][]string `json:"peer_groups,omitempty" bson:"peer_groups,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user