Files
Assistant/modules/capability/domain/fleet.go
2026-08-22 13:43:36 +03:00

61 lines
2.2 KiB
Go

package domain
import (
"errors"
"slices"
"sort"
"git.cin.su/m/Assistant/contracts/capability"
)
var ErrInvalidFleetReadiness = errors.New("invalid fleet readiness")
func BuildFleetReadiness(observedAt int64, members []capability.FleetMember) (capability.FleetReadiness, error) {
if observedAt < 1 || len(members) == 0 {
return capability.FleetReadiness{}, ErrInvalidFleetReadiness
}
result := capability.FleetReadiness{ObservedAtUnixMillis: observedAt, Members: append([]capability.FleetMember(nil), members...), FallbackTier: capability.FleetTierLifeboat}
seen := map[capability.FleetTier]bool{}
for i := range result.Members {
member := &result.Members[i]
if member.ProviderInstanceID == "" || member.ModelDescriptorID == "" || !validFleetTier(member.Tier) || seen[member.Tier] && member.Ready {
return capability.FleetReadiness{}, ErrInvalidFleetReadiness
}
if member.Ready {
seen[member.Tier] = true
}
}
for _, tier := range []capability.FleetTier{capability.FleetTierFast, capability.FleetTierMedium, capability.FleetTierHeavy, capability.FleetTierLifeboat} {
if seen[tier] {
result.ReadyTiers = append(result.ReadyTiers, tier)
}
}
return result, nil
}
func SelectFleetTier(readiness capability.FleetReadiness, preferred capability.FleetTier) (capability.FleetTier, error) {
if readiness.ObservedAtUnixMillis < 1 || len(readiness.Members) == 0 || !validFleetTier(readiness.FallbackTier) {
return "", ErrInvalidFleetReadiness
}
if slices.Contains(readiness.ReadyTiers, preferred) {
return preferred, nil
}
if slices.Contains(readiness.ReadyTiers, readiness.FallbackTier) {
return readiness.FallbackTier, nil
}
return "", ErrInvalidFleetReadiness
}
func validFleetTier(value capability.FleetTier) bool {
return value == capability.FleetTierFast || value == capability.FleetTierMedium || value == capability.FleetTierHeavy || value == capability.FleetTierLifeboat
}
func SortFleetMembers(members []capability.FleetMember) {
sort.SliceStable(members, func(i, j int) bool {
if members[i].Tier != members[j].Tier {
return members[i].Tier < members[j].Tier
}
return members[i].ProviderInstanceID < members[j].ProviderInstanceID
})
}