Repository: hashicorp/nomad
File: scheduler/reconciler/reconcile_cluster.go (Go)

Code before:
			downgradeNonCanary: isCanarying && !alloc.DeploymentStatus.IsCanary(),
			minJobVersion:      alloc.Job.Version,
			lost:               true,
		})
	}

	// Add remaining placement results
	if existing < group.Count {
		for _, name := range nameIndex.Next(uint(group.Count - existing)) {
			place = append(place, AllocPlaceResult{
				name:               name,
				taskGroup:          group,
				downgradeNonCanary: isCanarying,
			})
		}
	}

	return place
}

// placeAllocs either applies the placements calculated by computePlacements,
// or computes more placements based on whether the deployment is ready for
// placement and if the placement is already rescheduling or part of a failed
// deployment. The input deploymentPlaceReady is calculated as the deployment
// is not paused, failed, or canarying. It returns the number of allocs still
// needed, allocations to place, and allocations to stop.
func (a *AllocReconciler) placeAllocs(deploymentPlaceReady bool, desiredChanges *structs.DesiredUpdates,
	place []AllocPlaceResult, rescheduleNow, lost allocSet, disconnectUpdates map[string]*structs.Allocation,
	underProvisionedBy int) (int, []AllocPlaceResult, []AllocStopResult) {

	// Disconnecting allocs are not failing, but are included in rescheduleNow.
	// Create a new set that only includes the actual failures and compute
	// replacements based off that.
	failed := make(allocSet)
	for id, alloc := range rescheduleNow {
		_, ok := disconnectUpdates[id]
		if !ok && alloc.ClientStatus != structs.AllocClientStatusUnknown {
			failed[id] = alloc
		}
	}

	resultingPlacements := []AllocPlaceResult{}
	resultingAllocsToStop := []AllocStopResult{}

	// If the deployment is place ready, apply all placements and return
	if deploymentPlaceReady {
		desiredChanges.Place += uint64(len(place))
		// This relies on the computePlacements having built this set, which in
		// turn relies on len(lostLater) == 0.
		resultingPlacements = append(resultingPlacements, place...)


Review comment (bug):
I realize this text is mostly the existing text, but it feels like we're using "placements" here to mean both requested placements and the existing allocations on the client. Does this make it more clear?

```suggestion
// placeAllocs either applies the placements calculated by computePlacements,
// or computes more placements based on whether the deployment is ready for
// and if allocations are already rescheduling or part of a failed
// deployment. The input deploymentPlaceReady is calculated as the deployment
// is not paused, failed, or canarying. It returns the number of allocs still
// needed, allocations to place, and allocations to stop.
```

Code after:
			downgradeNonCanary: isCanarying && !alloc.DeploymentStatus.IsCanary(),
			minJobVersion:      alloc.Job.Version,
			lost:               true,
		})
	}

	// Add remaining placement results
	if existing < group.Count {
		for _, name := range nameIndex.Next(uint(group.Count - existing)) {
			place = append(place, AllocPlaceResult{
				name:               name,
				taskGroup:          group,
				downgradeNonCanary: isCanarying,
			})
		}
	}

	return place
}

// placeAllocs either applies the placements calculated by computePlacements,
// or computes more placements based on whether the deployment is ready for
// and if allocations are already rescheduling or part of a failed
// deployment. The input deploymentPlaceReady is calculated as the deployment
// is not paused, failed, or canarying. It returns the number of allocs still
// needed, allocations to place, and allocations to stop.
func (a *AllocReconciler) placeAllocs(deploymentPlaceReady bool, desiredChanges *structs.DesiredUpdates,
	place []AllocPlaceResult, rescheduleNow, lost allocSet, disconnectUpdates map[string]*structs.Allocation,
	underProvisionedBy int) (int, []AllocPlaceResult, []AllocStopResult) {

	// Disconnecting allocs are not failing, but are included in rescheduleNow.
	// Create a new set that only includes the actual failures and compute
	// replacements based off that.
	failed := make(allocSet)
	for id, alloc := range rescheduleNow {
		_, ok := disconnectUpdates[id]
		if !ok && alloc.ClientStatus != structs.AllocClientStatusUnknown {
			failed[id] = alloc
		}
	}

	resultingPlacements := []AllocPlaceResult{}
	resultingAllocsToStop := []AllocStopResult{}

	// If the deployment is place ready, apply all placements and return
	if deploymentPlaceReady {
		desiredChanges.Place += uint64(len(place))
		// This relies on the computePlacements having built this set, which in
		// turn relies on len(lostLater) == 0.
		resultingPlacements = append(resultingPlacements, place...)