SupervisorJob for independent failure in Kotlin - Time & Space Complexity
We want to understand how the time it takes to run a coroutine with a SupervisorJob changes as we add more child coroutines.
Specifically, we ask: how does failure in one child affect the overall execution time?
Analyze the time complexity of the following Kotlin coroutine code using SupervisorJob.
val supervisor = SupervisorJob()
val scope = CoroutineScope(Dispatchers.Default + supervisor)
repeat(n) { i ->
scope.launch {
delay(100L)
if (i == 0) throw Exception("Fail")
}
}
scope.coroutineContext[Job]?.join()
This code launches n child coroutines under a SupervisorJob, where one child fails independently.
Look for loops or repeated tasks that affect time.
- Primary operation: Launching and running n child coroutines.
- How many times: The repeat loop runs n times, creating n coroutines.
Each coroutine runs independently and takes about the same time, even if one fails.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 coroutines run, one fails, others continue |
| 100 | 100 coroutines run, failure in one does not stop others |
| 1000 | 1000 coroutines run independently, failure isolated |
Pattern observation: The total work grows linearly with n, and failure in one coroutine does not slow down others.
Time Complexity: O(n)
This means the total time grows roughly in direct proportion to the number of coroutines launched.
[X] Wrong: "If one coroutine fails, all others stop immediately, so total time is constant."
[OK] Correct: With SupervisorJob, failure in one child does not cancel siblings, so all coroutines still run independently.
Understanding how SupervisorJob isolates failures helps you explain concurrency control and error handling clearly in interviews.
"What if we replaced SupervisorJob with a regular Job? How would the time complexity change when one coroutine fails?"
Practice
SupervisorJob in Kotlin coroutines?Solution
Step 1: Understand SupervisorJob behavior
SupervisorJoblets child coroutines run independently so one failure doesn't affect others.Step 2: Compare with regular Job
RegularJobcancels all children if one fails, butSupervisorJobprevents this.Final Answer:
To allow child coroutines to fail independently without cancelling siblings -> Option BQuick Check:
SupervisorJob = independent failure [OK]
- Thinking SupervisorJob cancels all children on failure
- Confusing SupervisorJob with CoroutineScope
- Assuming SupervisorJob restarts failed coroutines
CoroutineScope with a SupervisorJob?Solution
Step 1: Identify correct SupervisorJob usage
Creating a scope withSupervisorJob()instance plus a dispatcher is correct syntax.Step 2: Check options for syntax correctness
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) usesSupervisorJob()constructor and adds dispatcher, which is valid.Final Answer:
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) -> Option AQuick Check:
SupervisorJob() + Dispatcher = correct scope [OK]
- Using SupervisorJob without parentheses
- Not adding a dispatcher to CoroutineScope
- Using Job() instead of SupervisorJob()
SupervisorJob:
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
scope.launch {
launch { throw Exception("Child 1 failed") }
launch { delay(100); println("Child 2 completed") }
}
What will be printed when this code runs?Solution
Step 1: Analyze SupervisorJob effect on children
WithSupervisorJob, failure in one child does not cancel siblings.Step 2: Trace coroutine execution
Child 1 throws exception immediately, but Child 2 delays and then prints "Child 2 completed".Final Answer:
Child 2 completed -> Option AQuick Check:
SupervisorJob allows sibling to finish [OK]
- Assuming all children cancel on one failure
- Expecting no output due to exception
- Confusing exception print with println output
SupervisorJob:
val scope = CoroutineScope(SupervisorJob)
scope.launch {
launch { throw Exception("Error") }
launch { println("Running") }
}Solution
Step 1: Check SupervisorJob usage
SupervisorJobis a function and must be called with parenthesesSupervisorJob().Step 2: Validate CoroutineScope creation
UsingSupervisorJobwithout parentheses is a syntax error; it must be an instance.Final Answer:
SupervisorJob is used without parentheses, causing a syntax error -> Option DQuick Check:
SupervisorJob() requires parentheses [OK]
- Omitting parentheses on SupervisorJob
- Thinking nested launch is invalid
- Assuming dispatcher is mandatory (optional)
SupervisorJob and handles exceptions independently?Solution
Step 1: Choose SupervisorJob for independent failure
UsingSupervisorJob()allows children to fail independently without cancelling siblings.Step 2: Handle exceptions in each child
Wrapping each child launch in try-catch blocks ensures exceptions are caught and handled independently within each coroutine.Final Answer:
Use CoroutineScope(SupervisorJob()) and wrap each child launch in try-catch blocks -> Option CQuick Check:
SupervisorJob + try-catch = safe independent children [OK]
- Ignoring exception handling in children
- Using Job() which cancels siblings on failure
- Using GlobalScope without SupervisorJob
Ready to prove it?
Pass the test and this pattern moves unknown
