func()

in pkg/instancetypes/instancetypes.go [113:166]


func (p *Provider) Get(ctx context.Context, instanceTypes []ec2types.InstanceType) ([]*Details, error) {
	p.logger.Printf("Getting instance types %v", instanceTypes)
	start := time.Now()
	calls := 0
	defer func() {
		p.logger.Printf("Took %s and %d calls to collect Instance Types", time.Since(start), calls)
	}()
	instanceTypeDetails := []*Details{}
	describeInstanceTypeOpts := &ec2.DescribeInstanceTypesInput{}
	if len(instanceTypes) != 0 {
		for _, it := range instanceTypes {
			if cachedIT, ok := p.cache.Get(string(it)); ok {
				instanceTypeDetails = append(instanceTypeDetails, cachedIT.(*Details))
			} else {
				// need to reassign, so we're not sharing the loop iterators memory space
				instanceType := it
				describeInstanceTypeOpts.InstanceTypes = append(describeInstanceTypeOpts.InstanceTypes, instanceType)
			}
		}
		// if we were able to retrieve all from cache, return here, else continue to do a remote lookup
		if len(describeInstanceTypeOpts.InstanceTypes) == 0 {
			return instanceTypeDetails, nil
		}
	} else if p.lastFullRefresh != nil && !p.isFullRefreshNeeded() {
		for _, item := range p.cache.Items() {
			instanceTypeDetails = append(instanceTypeDetails, item.Object.(*Details))
		}
		return instanceTypeDetails, nil
	}

	s := ec2.NewDescribeInstanceTypesPaginator(p.ec2Client, describeInstanceTypeOpts)

	for s.HasMorePages() {
		calls++
		instanceTypeOutput, err := s.NextPage(ctx)
		if err != nil {
			return nil, fmt.Errorf("failed to get next instance types page, %w", err)
		}
		for _, instanceTypeInfo := range instanceTypeOutput.InstanceTypes {
			itDetails := &Details{InstanceTypeInfo: instanceTypeInfo}
			instanceTypeDetails = append(instanceTypeDetails, itDetails)
			p.cache.SetDefault(string(instanceTypeInfo.InstanceType), itDetails)
		}
	}

	if len(instanceTypes) == 0 {
		now := time.Now().UTC()
		p.lastFullRefresh = &now
		if err := p.Save(); err != nil {
			return instanceTypeDetails, err
		}
	}
	return instanceTypeDetails, nil
}