Move DB I/O to Dispatchers.IO in AddEdit Expense/Recurring screen models #21
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
AddEditExpenseScreenModelandAddEditRecurringScreenModelboth perform DB I/O insidescreenModelScope.launch { ... }without switching off the main dispatcher:AddEditExpenseScreenModel.kt:54-55—getExpenses.awaitOne(id)on edit-mode initAddEditExpenseScreenModel.kt:99-102—upsertExpense.await(expense)insave()AddEditRecurringScreenModel.kt:63-64—getRecurringExpenses.awaitOne(id)on edit-mode initAddEditRecurringScreenModel.kt:123-126—upsertRecurringExpense.await(recurring)insave()screenModelScoperuns onDispatchers.Mainby default, so Room calls execute on the main thread. These need to run onDispatchers.IO.What to do
Wrap the interactor
await*calls inwithContext(Dispatchers.IO) { ... }in both screen models, so the suspending DB work happens off the main thread while the state-flow updates still run on the main dispatcher.For each of the four call sites above:
Imports to add to both files:
Architectural note (optional follow-up)
A more durable fix is to push the dispatcher switch into the interactor implementations (e.g. a base class or each
await*method), so every caller is safe by construction. Out of scope for this issue unless the user asks — keep this PR focused on the two screen models.Acceptance
AddEditExpenseScreenModelwrapsgetExpenses.awaitOneandupsertExpense.awaitinwithContext(Dispatchers.IO)AddEditRecurringScreenModelwrapsgetRecurringExpenses.awaitOneandupsertRecurringExpense.awaitinwithContext(Dispatchers.IO)launch { ... }after thewithContextblock)./gradlew assembleDebugsucceedsImplementation rule
Per
AGENTS.md— do not start implementation without explicit user sign-off on this issue. When working, check for related issues in the remote repo first.