diff --git a/CHANGELOG.md b/CHANGELOG.md index 57c5ca1d573..a46b4923021 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ * `Versions`: * `Exposed`: `0.59.0` -> `0.60.0` +* `Repo`: + * `Cache`: + * Add extensions `alsoInvalidate` and `alsoDoInvalidate` +* `Koin`: + * Add extensions `singleSuspend` and `factorySuspend` for defining of dependencies with suspendable blocks ## 0.25.1 diff --git a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt index 7e9bfe5a205..d5842a928c6 100644 --- a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt +++ b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt @@ -7,7 +7,9 @@ fun CoroutineScope.launchSynchronously(block: suspend CoroutineScope.() -> T val objectToSynchronize = Object() synchronized(objectToSynchronize) { launch(start = CoroutineStart.UNDISPATCHED) { - result = safelyWithResult(block) + result = runCatching { + block() + } }.invokeOnCompletion { synchronized(objectToSynchronize) { objectToSynchronize.notifyAll() diff --git a/koin/build.gradle b/koin/build.gradle index 466bf1b376f..7116800bfe3 100644 --- a/koin/build.gradle +++ b/koin/build.gradle @@ -16,7 +16,7 @@ kotlin { } jvmMain { dependencies { - api libs.kt.reflect + api project(":micro_utils.coroutines") } } androidMain { diff --git a/koin/src/jvmMain/kotlin/FactorySuspend.kt b/koin/src/jvmMain/kotlin/FactorySuspend.kt new file mode 100644 index 00000000000..17731956f47 --- /dev/null +++ b/koin/src/jvmMain/kotlin/FactorySuspend.kt @@ -0,0 +1,32 @@ +package dev.inmo.micro_utils.koin + +import dev.inmo.micro_utils.coroutines.doSynchronously +import kotlinx.coroutines.CoroutineScope +import org.koin.core.module.Module +import org.koin.core.parameter.ParametersHolder +import org.koin.core.qualifier.Qualifier +import org.koin.core.qualifier.StringQualifier +import org.koin.core.scope.Scope +import kotlin.reflect.KClass + +inline fun Module.factorySuspend( + qualifier: Qualifier? = null, + coroutineScope: CoroutineScope? = null, + noinline definition: suspend Scope.(ParametersHolder) -> T +) = factory( + qualifier, + if (coroutineScope == null) { + { + doSynchronously { + definition(it) + } + } + } else { + { + coroutineScope.doSynchronously { + definition(it) + } + } + } +) + diff --git a/koin/src/jvmMain/kotlin/SingleSuspend.kt b/koin/src/jvmMain/kotlin/SingleSuspend.kt new file mode 100644 index 00000000000..b43ea88cabc --- /dev/null +++ b/koin/src/jvmMain/kotlin/SingleSuspend.kt @@ -0,0 +1,32 @@ +package dev.inmo.micro_utils.koin + +import dev.inmo.micro_utils.coroutines.doSynchronously +import kotlinx.coroutines.CoroutineScope +import org.koin.core.module.Module +import org.koin.core.parameter.ParametersHolder +import org.koin.core.qualifier.StringQualifier +import org.koin.core.scope.Scope + +inline fun Module.singleSuspend( + qualifier: StringQualifier, + createdAtStart: Boolean = false, + coroutineScope: CoroutineScope? = null, + noinline definition: suspend Scope.(ParametersHolder) -> T +) = single( + qualifier, + createdAtStart, + if (coroutineScope == null) { + { + doSynchronously { + definition(it) + } + } + } else { + { + coroutineScope.doSynchronously { + definition(it) + } + } + } +) + diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/CacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/CacheRepo.kt index 6d683617fb0..8286091002b 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/CacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/CacheRepo.kt @@ -1,5 +1,8 @@ package dev.inmo.micro_utils.repos.cache +import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions +import kotlinx.coroutines.CoroutineScope + interface InvalidatableRepo { /** * Invalidates its internal data. It __may__ lead to autoreload of data. In case when repo makes autoreload, @@ -8,4 +11,14 @@ interface InvalidatableRepo { suspend fun invalidate() } +suspend fun T.alsoInvalidate() = also { + invalidate() +} + +fun T.alsoDoInvalidate(scope: CoroutineScope) = also { + scope.launchLoggingDropExceptions { + invalidate() + } +} + typealias CacheRepo = InvalidatableRepo