tezvyn:

How does Structured Concurrency handle cancellations and exceptions?

Curated by the Tezvyn teamSource: kotlinlang.orgintermediate
How does Structured Concurrency handle cancellations and exceptions?

This tests scope-bound lifecycle management preventing leaks. Cover scope cancellation cascading to children, exceptions propagating up to cancel siblings, and launch or async requiring a scope. A red flag is treating coroutines as fire-and-forget threads.

WHAT THIS TESTS: Structured Concurrency is the principle that every coroutine runs in a CoroutineScope with a bounded lifecycle, ensuring no work is launched that cannot be tracked or cancelled. Interviewers use this question to see if you understand the parent-child Job hierarchy, how cancellation flows through it, and how exceptions propagate differently depending on the builder and Job type. They want to know you can reason about scope boundaries rather than treating coroutines as unstructured background threads.

A GOOD ANSWER COVERS: First, define Structured Concurrency as the rule that coroutines form a tree where each coroutine has a parent Job, and the scope is the boundary that governs their lifetime. Second, explain cancellation: when a scope or parent Job is cancelled, the cancellation signal recursively traverses down to all children, so you never leave dangling work. Third, explain exception handling: if a child launched with launch fails, the exception propagates up to the parent, which then cancels all other children and fails the scope; with async, the exception is deferred until await is called, but it still propagates similarly if unhandled. Fourth, mention SupervisorJob as the escape hatch where child failures do not cancel siblings, useful for independent work units like UI widgets or monitoring tasks. Fifth, note that builders like launch and async are extensions on CoroutineScope, which enforces that you cannot fire a coroutine without a scope to manage it.

COMMON WRONG ANSWERS: A major red flag is saying GlobalScope is acceptable for production code because it lacks structured bounds and will leak work. Another is claiming that cancelling a scope has no effect on running children, or that async exceptions are silently swallowed if you forget await. Some candidates confuse thread interruption with coroutine cancellation; you should clarify that cancellation is cooperative and checked at suspension points, not forced. Finally, saying that all siblings survive a child failure without mentioning SupervisorJob shows shallow knowledge.

LIKELY FOLLOW-UPS: The interviewer may ask when to use SupervisorJob versus a regular Job, so be ready to say SupervisorJob is for independent subtasks where one failure should not tear down the rest. They might ask how to implement graceful shutdown, which involves cancelling the scope and then joining to wait for children to finish cleanup. Another follow-up is how to handle exceptions in async without crashing the parent, which leads to SupervisorJob plus try-catch around await. You might also be asked to compare RxJava disposal with structured concurrency cancellation.

ONE CONCRETE EXAMPLE: Imagine a ViewModel that launches two API calls with launch in its viewModelScope. If the ViewModel is cleared, the scope cancels, both network calls receive the cancellation signal, and the UI cannot be updated after destruction. If one API call throws an exception and the scope uses a regular Job, the second call is cancelled automatically. If the calls are independent, wrapping them in a SupervisorJob lets the second call continue even if the first fails.

Source: kotlinlang.org

Read the original → kotlinlang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.

How does Structured Concurrency handle cancellations and exceptions? · Tezvyn