// Returns instance that isn't marked down, if all instances are
// marked as down it will just choose a next one.
323646
func (pool *LoadBalancedPool) getInstance(key []byte, maxInstances int) (
	idx int,
	instance *instancePool,
	isDown bool,
	err error) {

	pool.lock.RLock()
	defer pool.lock.RUnlock()
	if len(pool.instanceList) == 0 {
		return 0, nil, false, errors.Newf("no available instances")
	}
	now := time.Now().Unix()
	numInstancesToTry := uint64(len(pool.instanceList))

	start := 0
	// map used to implement soft swapping to avoid picking the same instance multiple times
	// when we randomly pick instances for consistent-hashing. We could have used this actually
	// for the other strategies.
	// TODO(bashar): get rid of the random shuffle for the other strategies
	var idxMap map[int]int

	if pool.strategy == LBRoundRobin &&
		pool.activeSetSize < numInstancesToTry {
		numInstancesToTry = pool.activeSetSize
	} else if pool.strategy == LBConsistentHashing {

		// we must have a key
		if len(key) == 0 {
			return 0, nil, false, errors.Newf("key was not specified for consistent-hashing")
		} else if maxInstances <= 0 {
			return 0, nil, false, errors.Newf(
				"invalid maxInstances for consistent-hashing: %v", maxInstances)
		}

		// in case we're asked to try more than the number of servers we have
		if maxInstances > int(numInstancesToTry) {
			maxInstances = int(numInstancesToTry)
		}

		// let's find the closest server to start. We don't start from 0 in that case
		hash := pool.hashFunction(key, pool.hashSeed)
		// we need to find the closest server that hashes to >= hash.
		start = sort.Search(len(pool.instanceList), func(i int) bool {
			return pool.instanceHashes[i] >= hash
		})

		// In the case where hash > all elements, sort.Search returns len(pool.instanceList).
		// Hence, we mod the result
		start = start % len(pool.instanceHashes)

		idxMap = make(map[int]int)
	}

	for i := 0; uint64(i) < numInstancesToTry; i++ {
		switch pool.strategy {
		case LBRoundRobin:
			// In RoundRobin strategy instanceIdx keeps changing, to
			// achieve round robin load balancing.
			instanceIdx := atomic.AddUint64(&pool.instanceIdx, 1)
			idx = int(instanceIdx % numInstancesToTry)
		case LBSortedFixed:
			// In SortedFixed strategy instances are always traversed in same
			// exact order.
			idx = i
		case LBShuffledFixed:
			// In ShuffledFixed strategy instances are also always traversed in
			// same exact order.
			idx = i
		case LBConsistentHashing:
			// In ConsistentHashing strategy instances are picked up randomly between
			// start and start + numInstancesToTry. This is to load balance between
			// the alive servers that are closest to the key in the hash space

			// consistent-hashing will prefer availability over consistency. In the case some
			// server is down, we will try new servers in the hash-ring. The way we do this is by
			// picking random instances next (excluding already picked instances). That's why we
			// do a 'soft-swap' between already picked instance and move the start offset by 1
			// every time. We don't touch the pool.instanceList to make sure we don't
			// screw up any order. The swap below guarantees that start always has an idx that
			// has never been tried before.
			newStart := i + start
			idx = (newStart + rand2.Intn(maxInstances)) % len(pool.instanceList)
			// we need to swap idxMap[newStart] with idxMap[idx] (or fill them).
			var ok bool
			if idxMap[idx], ok = idxMap[idx]; ok {
				idxMap[newStart] = idxMap[idx]
			} else {
				idxMap[newStart] = idx
			}
			idxMap[idx] = newStart

			// we need to pick the correct idx after the swap
			idx = idxMap[newStart]
		}

		if pool.markDownUntil[idx] < now {
			break
		}
	}
	return idx, pool.instanceList[idx], (pool.markDownUntil[idx] >= now), nil
}
100758
func (r AbsResource) Instance(key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   r.Module,
		Resource: r.Resource.Instance(key),
	}
}
1100689
func (broker *lxdBroker) MaintainInstance(ctx context.ProviderCallContext, args environs.StartInstanceParams) error {
	machineID := args.InstanceConfig.MachineId

	// There's no InterfaceInfo we expect to get below.
	_, err := prepareOrGetContainerInterfaceInfo(
		broker.api,
		machineID,
		false, // maintain, do not allocate.
		lxdLogger,
	)
	return err
}
940488
func (c *Cloud) findInstanceByNodeName(nodeName types.NodeName) (*ec2.Instance, error) {
	privateDNSName := mapNodeNameToPrivateDNSName(nodeName)
	filters := []*ec2.Filter{
		newEc2Filter("private-dns-name", privateDNSName),
		// exclude instances in "terminated" state
		newEc2Filter("instance-state-name", aliveFilter...),
	}

	instances, err := c.describeInstances(filters)
	if err != nil {
		return nil, err
	}

	if len(instances) == 0 {
		return nil, nil
	}
	if len(instances) > 1 {
		return nil, fmt.Errorf("multiple instances found for name: %s", nodeName)
	}
	return instances[0], nil
}
377560
func (env *sessionEnviron) Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error) {
	if len(ids) == 0 {
		return nil, environs.ErrNoInstances
	}

	allInstances, err := env.AllInstances(ctx)
	if err != nil {
		return nil, errors.Annotate(err, "failed to get instances")
	}
	findInst := func(id instance.Id) instances.Instance {
		for _, inst := range allInstances {
			if id == inst.Id() {
				return inst
			}
		}
		return nil
	}

	var numFound int
	results := make([]instances.Instance, len(ids))
	for i, id := range ids {
		if inst := findInst(id); inst != nil {
			results[i] = inst
			numFound++
		}
	}
	if numFound == 0 {
		return nil, environs.ErrNoInstances
	} else if numFound != len(ids) {
		err = environs.ErrPartialInstances
	}
	return results, err
}
1017047
func (e *Environ) MaintainInstance(ctx envcontext.ProviderCallContext, args environs.StartInstanceParams) error {
	return nil
}
826432
func singleton() *Virtual {
	return &Virtual{
		order:  1,
		edge:   neverEdge,
		cost:   zero,
		degree: degreeZero,
		visit:  noNeighbors,
	}
}
530649
func (f *FakeCloud) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) {
	f.addCall("instance-shutdown-by-provider-id")
	return f.NodeShutdown, f.ErrShutdownByProviderID
}
1278226
func (as *availabilitySet) GetInstanceIDByNodeName(name string) (string, error) {
	var machine compute.VirtualMachine
	var err error

	machine, err = as.getVirtualMachine(types.NodeName(name))
	if err == cloudprovider.InstanceNotFound {
		return "", cloudprovider.InstanceNotFound
	}
	if err != nil {
		if as.CloudProviderBackoff {
			klog.V(2).Infof("GetInstanceIDByNodeName(%s) backing off", name)
			machine, err = as.GetVirtualMachineWithRetry(types.NodeName(name))
			if err != nil {
				klog.V(2).Infof("GetInstanceIDByNodeName(%s) abort backoff", name)
				return "", err
			}
		} else {
			return "", err
		}
	}

	resourceID := *machine.ID
	convertedResourceID, err := convertResourceGroupNameToLower(resourceID)
	if err != nil {
		klog.Errorf("convertResourceGroupNameToLower failed with error: %v", err)
		return "", err
	}
	return convertedResourceID, nil
}
889420
func (r Resource) Instance(key InstanceKey) ResourceInstance {
	return ResourceInstance{
		Resource: r,
		Key:      key,
	}
}
934865
func InstanceKeyLess(i, j InstanceKey) bool {
	iTy := instanceKeyType(i)
	jTy := instanceKeyType(j)

	switch {
	case i == j:
		return false
	case i == NoKey:
		return true
	case j == NoKey:
		return false
	case iTy != jTy:
		// The ordering here is arbitrary except that we want NoKeyType
		// to sort before the others, so we'll just use the enum values
		// of InstanceKeyType here (where NoKey is zero, sorting before
		// any other).
		return uint32(iTy) < uint32(jTy)
	case iTy == IntKeyType:
		return int(i.(IntKey)) < int(j.(IntKey))
	case iTy == StringKeyType:
		return string(i.(StringKey)) < string(j.(StringKey))
	default:
		// Shouldn't be possible to get down here in practice, since the
		// above is exhaustive.
		return false
	}
}
422744
func (m *MockMachineProvisioner) KeepInstance() (bool, error) {
	ret := m.ctrl.Call(m, "KeepInstance")
	ret0, _ := ret[0].(bool)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}
856254
func (cs *CSCloud) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) {
	return false, cloudprovider.NotImplemented
}
658371
func (client *Client) StopInstance(instanceId string, forceStop bool) error {
	args := StopInstanceArgs{
		InstanceId: instanceId,
		ForceStop:  forceStop,
	}
	response := StopInstanceResponse{}
	err := client.Invoke("StopInstance", &args, &response)
	return err
}
570091
func fetchExistingInstances(c context.Context, keys []*datastore.Key) ([]*Instance, error) {
	instances := make([]*Instance, len(keys))
	for i, k := range keys {
		instances[i] = &Instance{
			InstanceID: k.StringID(),
			Package:    k.Parent(),
		}
	}

	err := datastore.Get(c, instances)
	if err == nil {
		return instances, nil
	}

	merr, ok := err.(errors.MultiError)
	if !ok {
		return nil, errors.Annotate(err, "failed to fetch instances").Tag(transient.Tag).Err()
	}

	existing := instances[:0]
	for i, inst := range instances {
		switch err := merr[i]; {
		case err == nil:
			existing = append(existing, inst)
		case err != datastore.ErrNoSuchEntity:
			return nil, errors.Annotate(err, "failed to fetch instance %q", inst.InstanceID).Tag(transient.Tag).Err()
		}
	}
	return existing, nil
}
841015
func (client *Client) RebootInstance(instanceId string, forceStop bool) error {
	request := RebootInstanceArgs{
		InstanceId: instanceId,
		ForceStop:  forceStop,
	}
	response := RebootInstanceResponse{}
	err := client.Invoke("RebootInstance", &request, &response)
	return err
}
1292975
func (client *clientImpl) getInstanceCache(ctx context.Context) *internal.InstanceCache {
	client.instanceCacheInit.Do(func() {
		if client.CacheDir == "" {
			return
		}
		path := filepath.Join(client.CacheDir, "instances")
		client.instanceCache = internal.NewInstanceCache(fs.NewFileSystem(path, ""))
		logging.Infof(ctx, "cipd: using instance cache at %q", path)
	})
	return client.instanceCache
}