Skip to content

Commit ff0aab8

Browse files
committed
Document JobSupport state-transition & notification time-line
1 parent 6634ed7 commit ff0aab8

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

common/kotlinx-coroutines-core-common/src/JobSupport.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,45 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
8080
state without going to COMPLETING state)
8181
8282
Note, that the actual `_state` variable can also be a reference to atomic operation descriptor `OpDescriptor`
83+
84+
---------- TIMELINE of state changes and notification in Job lifecycle ----------
85+
86+
| The longest possible chain of events in shown, shorter versions cut-through intermediate states,
87+
| while still performing all the notifications in this order.
88+
89+
+ Job object is created
90+
## NEW: state == EMPTY_ACTIVE | is InactiveNodeList
91+
+ initParentJob / initParentJobInternal (invokes attachChild on its parent, initializes parentHandle)
92+
~ waits for start
93+
>> start / join / await invoked
94+
## ACTIVE: state == EMPTY_ACTIVE | is JobNode | is NodeList
95+
+ onStartInternal / onStart (lazy coroutine is started)
96+
~ active coroutine is working
97+
>> childFailed / fail invoked
98+
## FAILING: state is Finishing, state.rootCause != null
99+
------ failing listeners are not admitted anymore, invokeOnCompletion(onFailing=true) returns NonDisposableHandle
100+
------ new children get immediately cancelled, but are still admitted to the list
101+
+ onFailing
102+
+ notifyFailing (invoke all failing listeners -- cancel all children, suspended functions resume with exception)
103+
+ failParent (rootCause of failure is communicated to the parent, parent starts failing, too)
104+
~ waits for completion of coroutine body
105+
>> makeCompleting / makeCompletingOnce invoked
106+
## COMPLETING: state is Finishing, state.isCompleting == true
107+
------ new children are not admitted anymore, attachChild returns NonDisposableHandle
108+
~ waits for children
109+
>> last child completes
110+
- computes the final exception
111+
## SEALED: state is Finishing, state.isSealed == true
112+
------ cancel/childFailed returns false (cannot handle exceptions anymore)
113+
+ failParent (final exception is communicated to the parent, parent incorporates it)
114+
+ handleJobException ("launch" StandaloneCoroutine invokes CoroutineExceptionHandler)
115+
## COMPLETE: state !is Incomplete (CompletedExceptionally | Cancelled)
116+
------ completion listeners are not admitted anymore, invokeOnCompletion returns NonDisposableHandle
117+
+ parentHandle.dispose
118+
+ notifyCompletion (invoke all completion listeners)
119+
+ onCompletionInternal / onCompleted / onCompletedExceptionally
120+
121+
---------------------------------------------------------------------------------
83122
*/
84123

85124
// Note: use shared objects while we have no listeners

0 commit comments

Comments
 (0)