| name | dual-mode-persist-blocking-or-async |
| description | One suspend persistence body driven two ways — blocking on the shutdown path, where the write must complete before the scope dies, and fire-and-forget on periodic ticks — instead of two copies that drift apart. Use when saved state is correct while the app runs but wrong after a hard quit, when a teardown save silently does nothing, or when two save functions have grown different guards. |
One save body, two execution modes
Persistence has two callers with opposite requirements. The periodic one runs while everything is
alive and must not block anything. The teardown one runs while the object is being released — the
scope it would launch into is about to be cancelled, so a fire-and-forget write is simply lost.
Write the body once and let the caller choose how it runs:
fun mayBeSaveState(runBlocking: Boolean = false)
override fun mayBeSaveState(runBlocking: Boolean) {
val unit = suspend {
if (settings.saveStateEnabled.first() == TRUE) {
val itemId = currentItemState.value.entity?.id
(itemId != && collection.value.state == StateSource.STATE_INITIALIZED) {
settings.saveState(itemId, player.contentPosition)
repository.persist(ArrayList(collection.value..items))
}
}
}
(runBlocking) runBlocking { unit() } scope.launch { unit() }
}