Provides expert patterns and examples for Kotlin Coroutines and Flow, including structured concurrency, exception handling, reactive streams, best practices, and testing.
From antigravity-awesome-skillsnpx claudepluginhub sickn33/antigravity-awesome-skills --plugin antigravity-awesome-skillsThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
A guide to mastering asynchronous programming with Kotlin Coroutines. Covers advanced topics like structured concurrency, Flow transformations, exception handling, and testing strategies.
Flow.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()
)
}
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
}
}
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()
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
}
Dispatchers.IO for blocking I/O operations.ViewModel.onCleared).TestScope and runTest for unit testing coroutines.GlobalScope. It breaks structured concurrency and can lead to leaks.CancellationException unless you rethrow it.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.