Skip to content

Commit 2c2128e

Browse files
authored
Merge pull request #6598 from dsafdsa1/1k-limit
Add listManagedInstancesResults to GceCache.
2 parents 601da3f + 2b4fa12 commit 2c2128e

File tree

7 files changed

+247
-54
lines changed

7 files changed

+247
-54
lines changed

cluster-autoscaler/cloudprovider/gce/autoscaling_gce_client.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ type AutoscalingGceClient interface {
110110
FetchAvailableCpuPlatforms() (map[string][]string, error)
111111
FetchReservations() ([]*gce.Reservation, error)
112112
FetchReservationsInProject(projectId string) ([]*gce.Reservation, error)
113+
FetchListManagedInstancesResults(migRef GceRef) (string, error)
113114

114115
// modifying resources
115116
ResizeMig(GceRef, int64) error
@@ -234,6 +235,20 @@ func (client *autoscalingGceClientV1) FetchMigBasename(migRef GceRef) (string, e
234235
return igm.BaseInstanceName, nil
235236
}
236237

238+
func (client *autoscalingGceClientV1) FetchListManagedInstancesResults(migRef GceRef) (string, error) {
239+
registerRequest("instance_group_managers", "get")
240+
igm, err := client.gceService.InstanceGroupManagers.Get(migRef.Project, migRef.Zone, migRef.Name).Fields("listManagedInstancesResults").Do()
241+
if err != nil {
242+
if err, ok := err.(*googleapi.Error); ok {
243+
if err.Code == http.StatusNotFound {
244+
return "", errors.NewAutoscalerError(errors.NodeGroupDoesNotExistError, "%s", err.Error())
245+
}
246+
}
247+
return "", err
248+
}
249+
return igm.ListManagedInstancesResults, nil
250+
}
251+
237252
func (client *autoscalingGceClientV1) ResizeMig(migRef GceRef, size int64) error {
238253
registerRequest("instance_group_managers", "resize")
239254
op, err := client.gceService.InstanceGroupManagers.Resize(migRef.Project, migRef.Zone, migRef.Name, size).Do()

cluster-autoscaler/cloudprovider/gce/cache.go

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,36 +56,38 @@ type GceCache struct {
5656
cacheMutex sync.Mutex
5757

5858
// Cache content.
59-
migs map[GceRef]Mig
60-
instances map[GceRef][]GceInstance
61-
instancesUpdateTime map[GceRef]time.Time
62-
instancesToMig map[GceRef]GceRef
63-
instancesFromUnknownMig map[GceRef]bool
64-
resourceLimiter *cloudprovider.ResourceLimiter
65-
autoscalingOptionsCache map[GceRef]map[string]string
66-
machinesCache map[MachineTypeKey]MachineType
67-
migTargetSizeCache map[GceRef]int64
68-
migBaseNameCache map[GceRef]string
69-
instanceTemplateNameCache map[GceRef]string
70-
instanceTemplatesCache map[GceRef]*gce.InstanceTemplate
71-
kubeEnvCache map[GceRef]KubeEnv
59+
migs map[GceRef]Mig
60+
instances map[GceRef][]GceInstance
61+
instancesUpdateTime map[GceRef]time.Time
62+
instancesToMig map[GceRef]GceRef
63+
instancesFromUnknownMig map[GceRef]bool
64+
resourceLimiter *cloudprovider.ResourceLimiter
65+
autoscalingOptionsCache map[GceRef]map[string]string
66+
machinesCache map[MachineTypeKey]MachineType
67+
migTargetSizeCache map[GceRef]int64
68+
migBaseNameCache map[GceRef]string
69+
listManagedInstancesResultsCache map[GceRef]string
70+
instanceTemplateNameCache map[GceRef]string
71+
instanceTemplatesCache map[GceRef]*gce.InstanceTemplate
72+
kubeEnvCache map[GceRef]KubeEnv
7273
}
7374

7475
// NewGceCache creates empty GceCache.
7576
func NewGceCache() *GceCache {
7677
return &GceCache{
77-
migs: map[GceRef]Mig{},
78-
instances: map[GceRef][]GceInstance{},
79-
instancesUpdateTime: map[GceRef]time.Time{},
80-
instancesToMig: map[GceRef]GceRef{},
81-
instancesFromUnknownMig: map[GceRef]bool{},
82-
autoscalingOptionsCache: map[GceRef]map[string]string{},
83-
machinesCache: map[MachineTypeKey]MachineType{},
84-
migTargetSizeCache: map[GceRef]int64{},
85-
migBaseNameCache: map[GceRef]string{},
86-
instanceTemplateNameCache: map[GceRef]string{},
87-
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{},
88-
kubeEnvCache: map[GceRef]KubeEnv{},
78+
migs: map[GceRef]Mig{},
79+
instances: map[GceRef][]GceInstance{},
80+
instancesUpdateTime: map[GceRef]time.Time{},
81+
instancesToMig: map[GceRef]GceRef{},
82+
instancesFromUnknownMig: map[GceRef]bool{},
83+
autoscalingOptionsCache: map[GceRef]map[string]string{},
84+
machinesCache: map[MachineTypeKey]MachineType{},
85+
migTargetSizeCache: map[GceRef]int64{},
86+
migBaseNameCache: map[GceRef]string{},
87+
listManagedInstancesResultsCache: map[GceRef]string{},
88+
instanceTemplateNameCache: map[GceRef]string{},
89+
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{},
90+
kubeEnvCache: map[GceRef]KubeEnv{},
8991
}
9092
}
9193

@@ -515,3 +517,25 @@ func (gc *GceCache) InvalidateAllMigBasenames() {
515517
defer gc.cacheMutex.Unlock()
516518
gc.migBaseNameCache = make(map[GceRef]string)
517519
}
520+
521+
// SetListManagedInstancesResults sets listManagedInstancesResults for a given mig in cache
522+
func (gc *GceCache) SetListManagedInstancesResults(migRef GceRef, listManagedInstancesResults string) {
523+
gc.cacheMutex.Lock()
524+
defer gc.cacheMutex.Unlock()
525+
gc.listManagedInstancesResultsCache[migRef] = listManagedInstancesResults
526+
}
527+
528+
// GetListManagedInstancesResults gets listManagedInstancesResults for a given mig from cache.
529+
func (gc *GceCache) GetListManagedInstancesResults(migRef GceRef) (string, bool) {
530+
gc.cacheMutex.Lock()
531+
defer gc.cacheMutex.Unlock()
532+
listManagedInstancesResults, found := gc.listManagedInstancesResultsCache[migRef]
533+
return listManagedInstancesResults, found
534+
}
535+
536+
// InvalidateAllListManagedInstancesResults invalidates all listManagedInstancesResults entries.
537+
func (gc *GceCache) InvalidateAllListManagedInstancesResults() {
538+
gc.cacheMutex.Lock()
539+
defer gc.cacheMutex.Unlock()
540+
gc.listManagedInstancesResultsCache = make(map[GceRef]string)
541+
}

cluster-autoscaler/cloudprovider/gce/cache_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,29 @@ func TestMachineCache(t *testing.T) {
8787
})
8888
}
8989
}
90+
91+
func TestListManagedInstancesResultsCache(t *testing.T) {
92+
checkInCache := func(c *GceCache, migRef GceRef, expectedResults string) {
93+
result, found := c.GetListManagedInstancesResults(migRef)
94+
if !found {
95+
t.Errorf("Results not found for MIG ref: %s", migRef.String())
96+
}
97+
if result != expectedResults {
98+
t.Errorf("Expected results %s for MIG ref: %s, but got: %s", expectedResults, migRef.String(), result)
99+
}
100+
}
101+
migRef := GceRef{
102+
Project: "project",
103+
Zone: "us-test1",
104+
Name: "mig",
105+
}
106+
c := NewGceCache()
107+
c.SetListManagedInstancesResults(migRef, "PAGINATED")
108+
checkInCache(c, migRef, "PAGINATED")
109+
c.SetListManagedInstancesResults(migRef, "PAGELESS")
110+
checkInCache(c, migRef, "PAGELESS")
111+
c.InvalidateAllListManagedInstancesResults()
112+
if cacheSize := len(c.listManagedInstancesResultsCache); cacheSize > 0 {
113+
t.Errorf("Expected listManagedInstancesResultsCache to be empty, but it still contains %d entries", cacheSize)
114+
}
115+
}

cluster-autoscaler/cloudprovider/gce/gce_manager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ func (m *gceManagerImpl) Refresh() error {
300300
m.cache.InvalidateAllMigInstances()
301301
m.cache.InvalidateAllMigTargetSizes()
302302
m.cache.InvalidateAllMigBasenames()
303+
m.cache.InvalidateAllListManagedInstancesResults()
303304
m.cache.InvalidateAllMigInstanceTemplateNames()
304305
if m.lastRefresh.Add(refreshInterval).After(time.Now()) {
305306
return nil

cluster-autoscaler/cloudprovider/gce/gce_manager_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,12 @@ func newTestGceManager(t *testing.T, testServerURL string, regional bool) *gceMa
343343
{"us-central1-c", "n1-standard-1"}: {Name: "n1-standard-1", CPU: 1, Memory: 1},
344344
{"us-central1-f", "n1-standard-1"}: {Name: "n1-standard-1", CPU: 1, Memory: 1},
345345
},
346-
migTargetSizeCache: map[GceRef]int64{},
347-
instanceTemplateNameCache: map[GceRef]string{},
348-
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{},
349-
kubeEnvCache: map[GceRef]KubeEnv{},
350-
migBaseNameCache: map[GceRef]string{},
346+
migTargetSizeCache: map[GceRef]int64{},
347+
instanceTemplateNameCache: map[GceRef]string{},
348+
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{},
349+
kubeEnvCache: map[GceRef]KubeEnv{},
350+
migBaseNameCache: map[GceRef]string{},
351+
listManagedInstancesResultsCache: map[GceRef]string{},
351352
}
352353
migLister := NewMigLister(cache)
353354
manager := &gceManagerImpl{

cluster-autoscaler/cloudprovider/gce/mig_info_provider.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ type MigInfoProvider interface {
5252
// For custom machines cpu and memory information is based on parsing
5353
// machine name. For standard types it's retrieved from GCE API.
5454
GetMigMachineType(migRef GceRef) (MachineType, error)
55+
// Returns the pagination behavior of the listManagedInstances API method for a given MIG ref
56+
GetListManagedInstancesResults(migRef GceRef) (string, error)
5557
}
5658

5759
type timeProvider interface {
@@ -356,6 +358,7 @@ func (c *cachingMigInfoProvider) fillMigInfoCache() error {
356358
if registeredMigRefs[zoneMigRef] {
357359
c.cache.SetMigTargetSize(zoneMigRef, zoneMig.TargetSize)
358360
c.cache.SetMigBasename(zoneMigRef, zoneMig.BaseInstanceName)
361+
c.cache.SetListManagedInstancesResults(zoneMigRef, zoneMig.ListManagedInstancesResults)
359362

360363
templateUrl, err := url.Parse(zoneMig.InstanceTemplate)
361364
if err == nil {
@@ -411,3 +414,28 @@ func (c *cachingMigInfoProvider) GetMigMachineType(migRef GceRef) (MachineType,
411414
}
412415
return machine, nil
413416
}
417+
418+
func (c *cachingMigInfoProvider) GetListManagedInstancesResults(migRef GceRef) (string, error) {
419+
c.migInfoMutex.Lock()
420+
defer c.migInfoMutex.Unlock()
421+
422+
listManagedInstancesResults, found := c.cache.GetListManagedInstancesResults(migRef)
423+
if found {
424+
return listManagedInstancesResults, nil
425+
}
426+
427+
err := c.fillMigInfoCache()
428+
listManagedInstancesResults, found = c.cache.GetListManagedInstancesResults(migRef)
429+
if err == nil && found {
430+
return listManagedInstancesResults, nil
431+
}
432+
433+
// fallback to querying for a single mig
434+
listManagedInstancesResults, err = c.gceClient.FetchListManagedInstancesResults(migRef)
435+
if err != nil {
436+
c.migLister.HandleMigIssue(migRef, err)
437+
return "", err
438+
}
439+
c.cache.SetListManagedInstancesResults(migRef, listManagedInstancesResults)
440+
return listManagedInstancesResults, nil
441+
}

0 commit comments

Comments
 (0)