github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/design/tla/Tasks.tla (about) 1 ---------------------------- MODULE Tasks ---------------------------------- 2 3 EXTENDS TLC, Types 4 5 VARIABLE tasks \* The set of currently-allocated tasks 6 7 (* The expected type of each variable. TLA+ is an untyped language, but the model checker 8 can check that TasksTypeOK is true for every reachable state. *) 9 TasksTypeOK == 10 \* `tasks' is a subset of the set of all possible tasks 11 /\ tasks \in SUBSET Task 12 13 (* Update `tasks' by performing each update in `f', which is a function 14 mapping old tasks to new ones. *) 15 UpdateTasks(f) == 16 /\ Assert(\A t \in DOMAIN f : t \in tasks, "An old task does not exist!") 17 /\ Assert(\A t \in DOMAIN f : 18 LET t2 == f[t] 19 IN \* The updated version of `t' must have 20 /\ t.id = t2.id \* the same task ID, 21 /\ t.service = t2.service \* the same service ID, 22 /\ VSlot(t) = VSlot(t2), \* and the same vslot. 23 "An update changes a task's identity!") 24 \* Remove all the old tasks and add the new ones: 25 /\ tasks' = (tasks \ DOMAIN f) \union Range(f) 26 27 (* A `new' task belonging to service `sid' with the given slot, id, and desired state. *) 28 NewTask(sid, vslot, id, desired_state) == 29 [ 30 id |-> id, 31 service |-> sid, 32 status |-> [ state |-> new ], 33 desired_state |-> desired_state, 34 node |-> IF vslot \in Node THEN vslot ELSE unassigned, 35 slot |-> IF vslot \in Slot THEN vslot ELSE global 36 ] 37 38 39 \* A special ``state'' used when a task doesn't exist. 40 null == "null" 41 42 (* All the possible transitions, grouped by the component that performs them. *) 43 Transitions == [ 44 orchestrator |-> { 45 << null, new >> 46 }, 47 48 allocator |-> { 49 << new, pending >> 50 }, 51 52 scheduler |-> { 53 << pending, assigned >> 54 }, 55 56 agent |-> { 57 << assigned, accepted >>, 58 << accepted, preparing >>, 59 << preparing, ready >>, 60 << ready, starting >>, 61 << starting, running >>, 62 63 << assigned, rejected >>, 64 << accepted, rejected >>, 65 << preparing, rejected >>, 66 << ready, rejected >>, 67 << starting, rejected >>, 68 69 << running, complete >>, 70 << running, failed >>, 71 72 << running, shutdown >>, 73 74 << assigned, orphaned >>, 75 << accepted, orphaned >>, 76 << preparing, orphaned >>, 77 << ready, orphaned >>, 78 << starting, orphaned >>, 79 << running, orphaned >> 80 }, 81 82 reaper |-> { 83 << new, null >>, 84 << pending, null >>, 85 << rejected, null >>, 86 << complete, null >>, 87 << failed, null >>, 88 << shutdown, null >>, 89 << orphaned, null >> 90 } 91 ] 92 93 (* Check that `Transitions' itself is OK. *) 94 TransitionTableOK == 95 \* No transition moves to a lower-ranked state: 96 /\ \A actor \in DOMAIN Transitions : 97 \A trans \in Transitions[actor] : 98 \/ trans[1] = null 99 \/ trans[2] = null 100 \/ trans[1] \preceq trans[2] 101 (* Every source state has exactly one component which handles transitions out of that state. 102 Except for the case of the reaper removing `new' and `pending' tasks that are flagged 103 for removal. *) 104 /\ \A a1, a2 \in DOMAIN Transitions : 105 LET exceptions == { << new, null >>, << pending, null >> } 106 Source(a) == { s[1] : s \in Transitions[a] \ exceptions} 107 IN a1 # a2 => 108 Source(a1) \intersect Source(a2) = {} 109 110 ASSUME TransitionTableOK \* Note: ASSUME means ``check'' to TLC 111 112 =============================================================================