A screen loads a profile, a feed and a settings panel at the same time. The feed request fails. In a large share of mobile code, the profile and the settings disappear with it. Nobody designed that. It is the default behaviour of the concurrency model, and most teams have never been told.
Failure Travels by Default
Modern Android code runs concurrent work in a hierarchy: each task belongs to a parent, and the rule is strict in both directions. Cancel the parent and the children stop. Let one child fail and the parent fails, taking the siblings with it. The Kotlin documentation shows two concurrent tasks and notes "how both the first async and the awaiting parent are cancelled on failure of one of the children" (Kotlin).
That default is correct for work that only makes sense as a whole. It is wrong for three independent panels. The tool for independence exists and has a precise definition: it "propagates the cancellation in one direction only and cancels all its children only if it failed itself" (Kotlin).
The Fix That Is Not One
There is a widely copied shortcut that looks like the same thing. It was in our own article until this month. It detaches the work from the screen that started it, so the task "is not tied to the scope it was launched from and operates independently" (Kotlin), and it still lets one failure cancel the rest. The result is work that keeps running after the user has left, and no isolation in exchange.
Cancelling Is a Request
The second surprise is that stopping work is voluntary. "In Kotlin, coroutine cancellation is cooperative. Coroutines react to cancellation only when they cooperate by suspending or checking for cancellation explicitly" (Kotlin). Code that never checks runs to the end, on the customer's battery, for a result nobody will see.
What to Ask Your Team
- When one request on a screen fails, what happens to the others? The answer should be a decision, not a default.
- Do our error handlers also swallow cancellation? A catch-all does.
- Do our tests cover a stream that nobody is listening to? That is where a passing test hides a broken screen.
-Rocky
#SoftwareReliability #Kotlin #MobileEngineering #EngineeringDreams #StrategiaX
Originally published on ANDROID-ARCHITECT, the Android engineering blog of Strategia-X, with the code and the corrected examples.
