Marketplace kotlin-coroutines-expert
Expert patterns for Kotlin Coroutines and Flow, covering structured concurrency, error handling, and testing.
install
source · Clone the upstream repo
git clone https://github.com/aiskillstore/marketplace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aiskillstore/marketplace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/sickn33/kotlin-coroutines-expert" ~/.claude/skills/aiskillstore-marketplace-kotlin-coroutines-expert && rm -rf "$T"
manifest:
skills/sickn33/kotlin-coroutines-expert/SKILL.mdsource content
Kotlin Coroutines Expert
Overview
A guide to mastering asynchronous programming with Kotlin Coroutines. Covers advanced topics like structured concurrency,
Flow transformations, exception handling, and testing strategies.
When to Use This Skill
- Use when implementing asynchronous operations in Kotlin.
- Use when designing reactive data streams with
.Flow - Use when debugging coroutine cancellations or exceptions.
- Use when writing unit tests for suspending functions or Flows.
Step-by-Step Guide
1. Structured Concurrency
Always launch coroutines within a defined
CoroutineScope. Use coroutineScope or supervisorScope to group concurrent tasks.
suspend fun loadDashboardData(): DashboardData = coroutineScope { val userDeferred = async { userRepo.getUser() } val settingsDeferred = async { settingsRepo.getSettings() } DashboardData( user = userDeferred.await(), settings = settingsDeferred.await() ) }
2. Exception Handling
Use
CoroutineExceptionHandler for top-level scopes, but rely on try-catch within suspending functions for granular control.
val handler = CoroutineExceptionHandler { _, exception -> println("Caught $exception") } viewModelScope.launch(handler) { try { riskyOperation() } catch (e: IOException) { // Handle network error specifically } }
3. Reactive Streams with Flow
Use
StateFlow for state that needs to be retained, and SharedFlow for events.
// Cold Flow (Lazy) val searchResults: Flow<List<Item>> = searchQuery .debounce(300) .flatMapLatest { query -> searchRepo.search(query) } .flowOn(Dispatchers.IO) // Hot Flow (State) val uiState: StateFlow<UiState> = _uiState.asStateFlow()
Examples
Example 1: Parallel Execution with Error Handling
suspend fun fetchDataWithErrorHandling() = supervisorScope { val task1 = async { try { api.fetchA() } catch (e: Exception) { null } } val task2 = async { api.fetchB() } // If task2 fails, task1 is NOT cancelled because of supervisorScope val result1 = task1.await() val result2 = task2.await() // May throw }
Best Practices
- ✅ Do: Use
for blocking I/O operations.Dispatchers.IO - ✅ Do: Cancel scopes when they are no longer needed (e.g.,
).ViewModel.onCleared - ✅ Do: Use
andTestScope
for unit testing coroutines.runTest - ❌ Don't: Use
. It breaks structured concurrency and can lead to leaks.GlobalScope - ❌ Don't: Catch
unless you rethrow it.CancellationException
Troubleshooting
Problem: Coroutine test hangs or fails unpredictably. Solution: Ensure you are using
runTest and injecting TestDispatcher into your classes so you can control virtual time.