8000 Merge pull request #2867 from dperny/orphan-fewer-tasks · dani-docker/swarmkit@49a9b89 · GitHub
[go: up one dir, main page]

Skip to content

Commit 49a9b89

Browse files
dpernyDani Louca
authored andcommitted
Merge pull request moby#2867 from dperny/orphan-fewer-tasks
Only update non-terminal tasks on node removal.
1 parent 19e791f commit 49a9b89

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

manager/controlapi/node.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,23 @@ func orphanNodeTasks(tx store.Tx, nodeID string) error {
265265
return err
266266
}
267267
for _, task := range tasks {
268-
task.Status = api.TaskStatus{
269-
Timestamp: gogotypes.TimestampNow(),
270-
State: api.TaskStateOrphaned,
271-
Message: "Task belonged to a node that has been deleted",
268+
// this operation must occur within the same transaction boundary. If
269+
// we cannot accomplish this task orphaning in the same transaction, we
270+
// could crash or die between transactions and not get a chance to do
271+
// this. however, in cases were there is an exceptionally large number
272+
// of tasks for a node, this may cause the transaction to exceed the
273+
// max message size.
274+
//
275+
// therefore, we restrict updating to only tasks in a non-terminal
276+
// state. Tasks in a terminal state do not need to be updated.
277+
if task.Status.State < api.TaskStateCompleted {
278+
task.Status = api.TaskStatus{
279+
Timestamp: gogotypes.TimestampNow(),
280+
State: api.TaskStateOrphaned,
281+
Message: "Task belonged to a node that has been deleted",
282+
}
283+
store.UpdateTask(tx, task)
272284
}
273-
store.UpdateTask(tx, task)
274285
}
275286
return nil
276287
}

manager/controlapi/node_test.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ func TestUpdateNodeDemote(t *testing.T) {
942942
testUpdateNodeDemote(t)
943943
}
944944

945-
// TestRemoveNodeAttachments tests the unexported removeNodeAttachments
945+
// TestRemoveNodeAttachments tests the unexported orphanNodeTasks
946946
func TestOrphanNodeTasks(t *testing.T) {
947947
// first, set up a store and all that
948948
ts := newTestServer(t)
@@ -1081,7 +1081,28 @@ func TestOrphanNodeTasks(t *testing.T) {
10811081
},
10821082
},
10831083
}
1084-
return store.CreateTask(tx, task4)
1084+
if err := store.CreateTask(tx, task4); err != nil {
1085+
return err
1086+
}
1087+
1088+
// 5.) A regular task that's already in a terminal state on the node,
1089+
// which does not need to be updated.
1090+
task5 := &api.Task{
1091+
ID: "task5",
1092+
NodeID: "id2",
1093+
DesiredState: api.TaskStateRunning,
1094+
Status: api.TaskStatus{
1095+
// use TaskStateCompleted, as this is the earliest terminal
1096+
// state (this ensures we don't actually use <= instead of <)
1097+
State: api.TaskStateCompleted,
1098+
},
1099+
Spec: api.TaskSpec{
1100+
Runtime: &api.TaskSpec_Container{
1101+
Container: &api.ContainerSpec{},
1102+
},
1103+
},
1104+
}
1105+
return store.CreateTask(tx, task5)
10851106
})
10861107
require.NoError(t, err)
10871108

@@ -1096,8 +1117,7 @@ func TestOrphanNodeTasks(t *testing.T) {
10961117
ts.Store.View(func(tx store.ReadTx) {
10971118
tasks, err := store.FindTasks(tx, store.All)
10981119
require.NoError(t, err)
1099-
// should only be 3 tasks left
1100-
require.Len(t, tasks, 4)
1120+
require.Len(t, tasks, 5)
11011121
// and the list should not contain task1 or task2
11021122
for _, task := range tasks {
11031123
require.NotNil(t, task)

0 commit comments

Comments
 (0)
0