Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions pkg/apis/v1/ec2nodeclass_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,22 @@ func (in *EC2NodeClass) CapacityReservations() []CapacityReservation {
}

type ZoneInfo struct {
Zone string
ZoneID string
Zone string
ZoneID string
SubnetIDs []string
}

func (in *EC2NodeClass) ZoneInfo() []ZoneInfo {
return lo.Map(in.Status.Subnets, func(_ Subnet, i int) ZoneInfo {
subnetGroups := lo.GroupBy(in.Status.Subnets, func(s Subnet) string {
return s.ZoneID
})
return lo.MapToSlice(subnetGroups, func(zoneID string, subnets []Subnet) ZoneInfo {
return ZoneInfo{
Zone: in.Status.Subnets[i].Zone,
ZoneID: in.Status.Subnets[i].ZoneID,
Zone: subnets[0].Zone,
ZoneID: zoneID,
SubnetIDs: lo.Map(subnets, func(s Subnet, _ int) string {
return s.ID
}),
}
})
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 67 additions & 39 deletions pkg/cache/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
. "github.com/onsi/gomega"
. "sigs.k8s.io/karpenter/pkg/utils/testing"

v1 "github.com/aws/karpenter-provider-aws/pkg/apis/v1"
"github.com/aws/karpenter-provider-aws/pkg/cache"
"github.com/aws/karpenter-provider-aws/pkg/test"
)

var ctx context.Context
Expand All @@ -45,84 +47,110 @@ var _ = Describe("Cache", func() {
Context("Unavailable Offering Cache", func() {
It("should mark offerings as unavailable when calling MarkUnavailable", func() {
// offerings should initially not be marked as unavailable
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// m5.large on-demand should return that it's unavailable when we mark it
unavailableOfferingCache.MarkUnavailable(ctx, ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand, map[string]string{"reason": "test"})
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// m5.xlarge shouldn't return that it's unavailable when marking an unrelated instance type
unavailableOfferingCache.MarkUnavailable(ctx, ec2types.InstanceTypeM5Large, "test-zone-1b", karpv1.CapacityTypeOnDemand, map[string]string{"reason": "test"})
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// m5.xlarge spot should return that it's unavailable when we mark it
unavailableOfferingCache.MarkUnavailable(ctx, ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot, map[string]string{"reason": "test"})
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeTrue())
})
It("should mark offerings as unavailable with fleet error reasons", func() {
// offerings should initially not be marked as unavailable
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// m5.large on-demand should return that it's unavailable when we mark it
unavailableOfferingCache.MarkUnavailable(ctx, ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand, map[string]string{
"reason": "InsufficientInstanceCapacity",
})
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// m5.xlarge shouldn't return that it's unavailable when marking an unrelated instance type
unavailableOfferingCache.MarkUnavailable(ctx, ec2types.InstanceTypeM5Large, "test-zone-1b", karpv1.CapacityTypeOnDemand, map[string]string{
"reason": "InsufficientInstanceCapacity",
})
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// m5.xlarge spot should return that it's unavailable when we mark it
unavailableOfferingCache.MarkUnavailable(ctx, ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot, map[string]string{
"reason": "InsufficientInstanceCapacity",
})
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeTrue())
})
It("should mark offerings as unavailable when calling MarkCapacityTypeUnavailable", func() {
// offerings should initially not be marked as unavailable
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeFalse())

// mark all spot offerings as unavailable
unavailableOfferingCache.MarkCapacityTypeUnavailable(karpv1.CapacityTypeSpot)
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", []string{}, karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeTrue())

// mark all on-demand offerings as unavailable
unavailableOfferingCache.MarkCapacityTypeUnavailable(karpv1.CapacityTypeOnDemand)
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", []string{}, karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", []string{}, karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", []string{}, karpv1.CapacityTypeSpot)).To(BeTrue())
})
It("should mark offerings as unavailable when calling MarkAZUnavailable", func() {
zoneInfo := []v1.ZoneInfo{
{
Zone: "test-zone-1a",
ZoneID: "tstz1-1a",
SubnetIDs: []string{"subnet-test1"},
},
{
Zone: "test-zone-1b",
ZoneID: "tstz1-1b",
SubnetIDs: []string{"subnet-test2"},
},
{
Zone: "test-zone-1c",
ZoneID: "tstz1-1c",
SubnetIDs: []string{"subnet-test3"},
},
}

// offerings should initially not be marked as unavailable
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a",
test.GetSubetsFromZone("test-zone-1a", zoneInfo), karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a",
test.GetSubetsFromZone("test-zone-1a", zoneInfo), karpv1.CapacityTypeOnDemand)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a",
test.GetSubetsFromZone("test-zone-1a", zoneInfo), karpv1.CapacityTypeSpot)).To(BeFalse())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b",
test.GetSubetsFromZone("test-zone-1b", zoneInfo), karpv1.CapacityTypeSpot)).To(BeFalse())

// mark all test-zone-1a offerings as unavailable
unavailableOfferingCache.MarkAZUnavailable("test-zone-1a")
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a", karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b", karpv1.CapacityTypeSpot)).To(BeFalse())
unavailableOfferingCache.MarkSubnetUnavailable("subnet-test1")
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Large, "test-zone-1a",
test.GetSubetsFromZone("test-zone-1a", zoneInfo), karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a",
test.GetSubetsFromZone("test-zone-1a", zoneInfo), karpv1.CapacityTypeOnDemand)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1a",
test.GetSubetsFromZone("test-zone-1a", zoneInfo), karpv1.CapacityTypeSpot)).To(BeTrue())
Expect(unavailableOfferingCache.IsUnavailable(ec2types.InstanceTypeM5Xlarge, "test-zone-1b",
test.GetSubetsFromZone("test-zone-1b", zoneInfo), karpv1.CapacityTypeSpot)).To(BeFalse())
})
It("should increase sequence number when unavailability changes", func() {
// sequence numbers should initially be 0
Expand All @@ -140,12 +168,12 @@ var _ = Describe("Cache", func() {
Expect(unavailableOfferingCache.SeqNum(ec2types.InstanceTypeM5Xlarge)).To(BeNumerically("==", 1))

// marking test-zone-1a as unavailable should increase the sequence number for all instance types
unavailableOfferingCache.MarkAZUnavailable("test-zone-1a")
unavailableOfferingCache.MarkSubnetUnavailable("subnet-test1")
Expect(unavailableOfferingCache.SeqNum(ec2types.InstanceTypeM5Large)).To(BeNumerically("==", 2))
Expect(unavailableOfferingCache.SeqNum(ec2types.InstanceTypeM5Xlarge)).To(BeNumerically("==", 2))

// marking test-zone-1b as unavailable should increase the sequence number for all instance types
unavailableOfferingCache.MarkAZUnavailable("test-zone-1b")
unavailableOfferingCache.MarkSubnetUnavailable("subnet-test2")
Expect(unavailableOfferingCache.SeqNum(ec2types.InstanceTypeM5Large)).To(BeNumerically("==", 3))
Expect(unavailableOfferingCache.SeqNum(ec2types.InstanceTypeM5Xlarge)).To(BeNumerically("==", 3))

Expand Down
32 changes: 19 additions & 13 deletions pkg/cache/unavailableofferings.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"sync/atomic"

ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/samber/lo"
"sigs.k8s.io/controller-runtime/pkg/log"

"github.com/patrickmn/go-cache"
Expand All @@ -39,8 +40,8 @@ type UnavailableOfferings struct {
capacityTypeCache *cache.Cache
capacityTypeCacheSeqNum atomic.Uint64

azCache *cache.Cache
azCacheSeqNum atomic.Uint64
subnetCache *cache.Cache
subnetCacheSeqNum atomic.Uint64
}

func NewUnavailableOfferings() *UnavailableOfferings {
Expand All @@ -50,7 +51,7 @@ func NewUnavailableOfferings() *UnavailableOfferings {
offeringCacheSeqNum: map[ec2types.InstanceType]uint64{},

capacityTypeCache: cache.New(UnavailableOfferingsTTL, UnavailableOfferingsCleanupInterval),
azCache: cache.New(UnavailableOfferingsTTL, UnavailableOfferingsCleanupInterval),
subnetCache: cache.New(UnavailableOfferingsTTL, UnavailableOfferingsCleanupInterval),
}
uo.offeringCache.OnEvicted(func(k string, _ any) {
elems := strings.Split(k, ":")
Expand All @@ -64,8 +65,8 @@ func NewUnavailableOfferings() *UnavailableOfferings {
uo.capacityTypeCache.OnEvicted(func(k string, _ any) {
uo.capacityTypeCacheSeqNum.Add(1)
})
uo.azCache.OnEvicted(func(k string, _ any) {
uo.azCacheSeqNum.Add(1)
uo.subnetCache.OnEvicted(func(k string, _ any) {
uo.subnetCacheSeqNum.Add(1)
})
return uo
}
Expand All @@ -76,15 +77,20 @@ func (u *UnavailableOfferings) SeqNum(instanceType ec2types.InstanceType) uint64
defer u.offeringCacheSeqNumMu.RUnlock()

v := u.offeringCacheSeqNum[instanceType]
return v + u.capacityTypeCacheSeqNum.Load() + u.azCacheSeqNum.Load()
return v + u.capacityTypeCacheSeqNum.Load() + u.subnetCacheSeqNum.Load()
}

// IsUnavailable returns true if the offering appears in the cache
func (u *UnavailableOfferings) IsUnavailable(instanceType ec2types.InstanceType, zone, capacityType string) bool {
func (u *UnavailableOfferings) IsUnavailable(instanceType ec2types.InstanceType, zone string, subnetIDs []string, capacityType string) bool {
_, offeringFound := u.offeringCache.Get(u.key(instanceType, zone, capacityType))
_, capacityTypeFound := u.capacityTypeCache.Get(capacityType)
_, azFound := u.azCache.Get(zone)
return offeringFound || capacityTypeFound || azFound
// we should only mark the zone as unavaialble if all subnets are in the cache
// if there are no subnets in the list, it should not cause unavaialbility as we expect scheduling requirements to capture that
subnetFoundInAZ := lo.Reduce(subnetIDs, func(agg bool, subnetID string, _ int) bool {
_, subnetFound := u.subnetCache.Get(subnetID)
return agg && subnetFound
}, true)
return offeringFound || capacityTypeFound || (subnetFoundInAZ && len(subnetIDs) != 0)
}

// MarkUnavailable communicates recently observed temporary capacity shortages in the provided offerings
Expand Down Expand Up @@ -115,9 +121,9 @@ func (u *UnavailableOfferings) MarkCapacityTypeUnavailable(capacityType string)
u.capacityTypeCacheSeqNum.Add(1)
}

func (u *UnavailableOfferings) MarkAZUnavailable(zone string) {
u.azCache.SetDefault(zone, struct{}{})
u.azCacheSeqNum.Add(1)
func (u *UnavailableOfferings) MarkSubnetUnavailable(subnetID string) {
u.subnetCache.SetDefault(subnetID, struct{}{})
u.subnetCacheSeqNum.Add(1)
}

func (u *UnavailableOfferings) Delete(instanceType ec2types.InstanceType, zone string, capacityType string) {
Expand All @@ -127,7 +133,7 @@ func (u *UnavailableOfferings) Delete(instanceType ec2types.InstanceType, zone s
func (u *UnavailableOfferings) Flush() {
u.offeringCache.Flush()
u.capacityTypeCache.Flush()
u.azCache.Flush()
u.subnetCache.Flush()
}

// key returns the cache key for all offerings in the cache
Expand Down
Loading