diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cde6be0ffe..f39632956be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.4.33 + +* `Versions`: + * `Ktor`: `1.5.2` -> `1.5.3` +* `Coroutines` + * Add `WeakJob` workaround: + * `CoroutineScope#weakLaunch` + * `CoroutineScope#weakAsync` + ## 0.4.32 * `Versions`: diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt new file mode 100644 index 00000000000..c020a359ecb --- /dev/null +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt @@ -0,0 +1,31 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.* +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +private fun CoroutineScope.createWeakSubScope() = CoroutineScope(coroutineContext.minusKey(Job)).also { newScope -> + coroutineContext.job.invokeOnCompletion { newScope.cancel() } +} + +fun CoroutineScope.weakLaunch( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> Unit +): Job { + val scope = createWeakSubScope() + val job = scope.launch(context, start, block) + job.invokeOnCompletion { scope.cancel() } + return job +} + +fun CoroutineScope.weakAsync( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> T +): Deferred { + val scope = createWeakSubScope() + val deferred = scope.async(context, start, block) + deferred.invokeOnCompletion { scope.cancel() } + return deferred +} diff --git a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt new file mode 100644 index 00000000000..311b3b05b3b --- /dev/null +++ b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt @@ -0,0 +1,40 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.* +import org.junit.Test + +class WeakJob { + @Test + fun `test that weak jobs works correctly`() { + val scope = CoroutineScope(Dispatchers.Default) + lateinit var weakLaunchJob: Job + lateinit var weakAsyncJob: Job + scope.launchSynchronously { + val completeDeferred = Job() + coroutineScope { + weakLaunchJob = weakLaunch { + while (isActive) { + delay(100L) + } + } + weakAsyncJob = weakAsync { + while (isActive) { + delay(100L) + } + } + + coroutineContext.job.invokeOnCompletion { + scope.launch { + delay(1000L) + completeDeferred.complete() + } + } + launch { delay(1000L); cancel() } + } + completeDeferred.join() + } + + assert(!weakLaunchJob.isActive) + assert(!weakAsyncJob.isActive) + } +} diff --git a/gradle.properties b/gradle.properties index c7e30d18914..a99d8f64d50 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ kotlin_coroutines_version=1.4.3 kotlin_serialisation_core_version=1.1.0 kotlin_exposed_version=0.30.1 -ktor_version=1.5.2 +ktor_version=1.5.3 klockVersion=2.0.7 @@ -44,5 +44,5 @@ dokka_version=1.4.30 # Project data group=dev.inmo -version=0.4.32 -android_code_version=36 +version=0.4.33 +android_code_version=37