Skip to content

Instantly share code, notes, and snippets.

@aleweichandt
Created August 16, 2021 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aleweichandt/ff8da71c12c44fd4c8e26b9a174b680e to your computer and use it in GitHub Desktop.
Save aleweichandt/ff8da71c12c44fd4c8e26b9a174b680e to your computer and use it in GitHub Desktop.
Repository resource
class Resource<in Input, out Output>(
private val remoteFetch: suspend (Input) -> Output?,
private val localFetch: suspend (Input) -> Output?,
private val localStore: suspend (Output) -> Unit,
private val localDelete: suspend () -> Unit,
private val refreshControl: RefreshControl = RefreshControl()
) : RefreshControl.Listener, ITimeLimitedResource by refreshControl {
init { refreshControl.addListener(this) }
// Public API
suspend fun query(args: Input, force: Boolean = false): Flow<Output?> = flow {
if (!force) {
fetchFromLocal(args)?.run { emit(this) }
}
if (refreshControl.isExpired() || force) {
fetchFromRemote(args).run { emit(this) }
}
}
override suspend fun cleanup() {
deleteLocal()
}
// Private API
private suspend fun deleteLocal() = kotlin.runCatching {
localDelete()
}.getOrNull()
private suspend fun fetchFromLocal(args: Input) = kotlin.runCatching {
localFetch(args)
}.getOrNull()
private suspend fun fetchFromRemote(args: Input) = kotlin.runCatching {
remoteFetch(args)
}.getOrThrow()?.also {
kotlin.runCatching {
localStore(it)
refreshControl.refresh()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment