Skip inplace update on terminal batch allocation
This PR skips adding an inplace update to a successfully terminal batch job to the plan. This avoids extra data in the plan and avoids triggering updates on all clients that have the terminal allocation. This is matching behavior of the service scheduler. /cc @armon for review
This commit is contained in:
parent
3f68aae7ab
commit
2c31d4036b
|
@ -2490,6 +2490,61 @@ func TestBatchSched_ReRun_SuccessfullyFinishedAlloc(t *testing.T) {
|
|||
h.AssertEvalStatus(t, structs.EvalStatusComplete)
|
||||
}
|
||||
|
||||
// This test checks that terminal allocations that receive an in-place updated
|
||||
// are not added to the plan
|
||||
func TestBatchSched_JobModify_InPlace_Terminal(t *testing.T) {
|
||||
h := NewHarness(t)
|
||||
|
||||
// Create some nodes
|
||||
var nodes []*structs.Node
|
||||
for i := 0; i < 10; i++ {
|
||||
node := mock.Node()
|
||||
nodes = append(nodes, node)
|
||||
noErr(t, h.State.UpsertNode(h.NextIndex(), node))
|
||||
}
|
||||
|
||||
// Generate a fake job with allocations
|
||||
job := mock.Job()
|
||||
job.Type = structs.JobTypeBatch
|
||||
noErr(t, h.State.UpsertJob(h.NextIndex(), job))
|
||||
|
||||
var allocs []*structs.Allocation
|
||||
for i := 0; i < 10; i++ {
|
||||
alloc := mock.Alloc()
|
||||
alloc.Job = job
|
||||
alloc.JobID = job.ID
|
||||
alloc.NodeID = nodes[i].ID
|
||||
alloc.Name = fmt.Sprintf("my-job.web[%d]", i)
|
||||
alloc.ClientStatus = structs.AllocClientStatusComplete
|
||||
allocs = append(allocs, alloc)
|
||||
}
|
||||
noErr(t, h.State.UpsertAllocs(h.NextIndex(), allocs))
|
||||
|
||||
// Update the job
|
||||
job2 := mock.Job()
|
||||
job2.ID = job.ID
|
||||
noErr(t, h.State.UpsertJob(h.NextIndex(), job2))
|
||||
|
||||
// Create a mock evaluation to deal with drain
|
||||
eval := &structs.Evaluation{
|
||||
ID: structs.GenerateUUID(),
|
||||
Priority: 50,
|
||||
TriggeredBy: structs.EvalTriggerJobRegister,
|
||||
JobID: job.ID,
|
||||
}
|
||||
|
||||
// Process the evaluation
|
||||
err := h.Process(NewBatchScheduler, eval)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Ensure no plan
|
||||
if len(h.Plans) != 0 {
|
||||
t.Fatalf("bad: %#v", h.Plans)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenericSched_FilterCompleteAllocs(t *testing.T) {
|
||||
running := mock.Alloc()
|
||||
desiredStop := mock.Alloc()
|
||||
|
|
|
@ -455,6 +455,15 @@ func setStatus(logger *log.Logger, planner Planner,
|
|||
func inplaceUpdate(ctx Context, eval *structs.Evaluation, job *structs.Job,
|
||||
stack Stack, updates []allocTuple) (destructive, inplace []allocTuple) {
|
||||
|
||||
// doInplace manipulates the updates map to make the current allocation
|
||||
// an inplace update.
|
||||
doInplace := func(cur, last, inplaceCount *int) {
|
||||
updates[*cur], updates[*last-1] = updates[*last-1], updates[*cur]
|
||||
*cur--
|
||||
*last--
|
||||
*inplaceCount++
|
||||
}
|
||||
|
||||
ws := memdb.NewWatchSet()
|
||||
n := len(updates)
|
||||
inplaceCount := 0
|
||||
|
@ -469,6 +478,15 @@ func inplaceUpdate(ctx Context, eval *structs.Evaluation, job *structs.Job,
|
|||
continue
|
||||
}
|
||||
|
||||
// Terminal batch allocations are not filtered when they are completed
|
||||
// successfully. We should avoid adding the allocation to the plan in
|
||||
// the case that it is an in-place update to avoid both additional data
|
||||
// in the plan and work for the clients.
|
||||
if update.Alloc.TerminalStatus() {
|
||||
doInplace(&i, &n, &inplaceCount)
|
||||
continue
|
||||
}
|
||||
|
||||
// Get the existing node
|
||||
node, err := ctx.State().NodeByID(ws, update.Alloc.NodeID)
|
||||
if err != nil {
|
||||
|
@ -523,11 +541,9 @@ func inplaceUpdate(ctx Context, eval *structs.Evaluation, job *structs.Job,
|
|||
ctx.Plan().AppendAlloc(newAlloc)
|
||||
|
||||
// Remove this allocation from the slice
|
||||
updates[i], updates[n-1] = updates[n-1], updates[i]
|
||||
i--
|
||||
n--
|
||||
inplaceCount++
|
||||
doInplace(&i, &n, &inplaceCount)
|
||||
}
|
||||
|
||||
if len(updates) > 0 {
|
||||
ctx.Logger().Printf("[DEBUG] sched: %#v: %d in-place updates of %d", eval, inplaceCount, len(updates))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue