19320: Deduplicate instance types in spot price request.
[arvados.git] / lib / cloud / ec2 / ec2.go
index 93c308bcb13f328185aaf4aa6e0421bfd4fe62f8..b90eff6d571301085c2acd3d9bb8df56d1cfe54c 100644 (file)
@@ -246,10 +246,6 @@ func (instanceSet *ec2InstanceSet) Create(
                }
        }
 
-       if instanceSet.ec2config.SpotPriceUpdateInterval <= 0 {
-               instanceSet.ec2config.SpotPriceUpdateInterval = arvados.Duration(24 * time.Hour)
-       }
-
        rsv, err := instanceSet.client.RunInstances(&rii)
        err = wrapError(err, &instanceSet.throttleDelayCreate)
        if err != nil {
@@ -296,7 +292,7 @@ func (instanceSet *ec2InstanceSet) Instances(tags cloud.InstanceTags) (instances
                }
                dii.NextToken = dio.NextToken
        }
-       if needAZs {
+       if needAZs && instanceSet.ec2config.SpotPriceUpdateInterval > 0 {
                az := map[string]string{}
                err := instanceSet.client.DescribeInstanceStatusPages(&ec2.DescribeInstanceStatusInput{
                        IncludeAllInstances: aws.Bool(true),
@@ -341,7 +337,8 @@ func (instanceSet *ec2InstanceSet) updateSpotPrices(instances []cloud.Instance)
        updateTime := time.Now()
        staleTime := updateTime.Add(-instanceSet.ec2config.SpotPriceUpdateInterval.Duration())
        needUpdate := false
-       var typeFilterValues []*string
+       allTypes := map[string]bool{}
+
        for _, inst := range instances {
                ec2inst := inst.(*ec2Instance).instance
                if aws.StringValue(ec2inst.InstanceLifecycle) == "spot" {
@@ -353,12 +350,16 @@ func (instanceSet *ec2InstanceSet) updateSpotPrices(instances []cloud.Instance)
                        if instanceSet.pricesUpdated[pk].Before(staleTime) {
                                needUpdate = true
                        }
-                       typeFilterValues = append(typeFilterValues, ec2inst.InstanceType)
+                       allTypes[*ec2inst.InstanceType] = true
                }
        }
        if !needUpdate {
                return
        }
+       var typeFilterValues []*string
+       for instanceType := range allTypes {
+               typeFilterValues = append(typeFilterValues, aws.String(instanceType))
+       }
        // Get 3x update interval worth of pricing data. (Ideally the
        // AWS API would tell us "we have shown you all of the price
        // changes up to time T", but it doesn't, so we'll just ask
@@ -510,6 +511,9 @@ func (inst *ec2Instance) VerifyHostKey(ssh.PublicKey, *ssh.Client) error {
 func (inst *ec2Instance) PriceHistory(instType arvados.InstanceType) []cloud.InstancePrice {
        inst.provider.pricesLock.Lock()
        defer inst.provider.pricesLock.Unlock()
+       // Note updateSpotPrices currently populates
+       // inst.provider.prices only for spot instances, so if
+       // spot==false here, we will return no data.
        pk := priceKey{
                instanceType:     *inst.instance.InstanceType,
                spot:             aws.StringValue(inst.instance.InstanceLifecycle) == "spot",