diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ed2d053e1..3db6aa60047 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.20.52 +* `Coroutines`: + * Small rework of weak jobs: add `WeakScope` factory, rename old weal extensions and add kdocs + ## 0.20.51 * `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 index 48a49f295db..a00840d8f37 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt @@ -4,6 +4,12 @@ import kotlinx.coroutines.* import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext +/** + * Created [CoroutineScope] which will [launch] listening of [context] job completing and drop itself. Current weak + * scope **will not** be attached to [context] directly. So, this [CoroutineScope] will not prevent parent one from + * cancelling if it is launched with [supervisorScope] or [coroutineScope], but still will follow closing status + * of parent [Job] + */ fun WeakScope( context: CoroutineContext ) = CoroutineScope(context.minusKey(Job) + Job()).also { newScope -> @@ -13,10 +19,20 @@ fun WeakScope( } } +/** + * Created [CoroutineScope] which will [launch] listening of [scope] [CoroutineContext] job completing and drop itself. Current weak + * scope **will not** be attached to [scope] [CoroutineContext] directly. So, this [CoroutineScope] will not prevent parent one from + * cancelling if it is launched with [supervisorScope] or [coroutineScope], but still will follow closing status + * of parent [Job] + */ fun WeakScope( scope: CoroutineScope ) = WeakScope(scope.coroutineContext) +/** + * [this] [CoroutineScope] will be used as base for [WeakScope]. Other parameters ([context], [start], [block]) + * will be used to [launch] [Job] + */ fun CoroutineScope.launchWeak( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, @@ -28,6 +44,10 @@ fun CoroutineScope.launchWeak( return job } +/** + * [this] [CoroutineScope] will be used as base for [WeakScope]. Other parameters ([context], [start], [block]) + * will be used to create [async] [Deferred] + */ fun CoroutineScope.asyncWeak( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, @@ -38,6 +58,7 @@ fun CoroutineScope.asyncWeak( deferred.invokeOnCompletion { scope.cancel() } return deferred } + @Deprecated("Renamed", ReplaceWith("launchWeak(context, start, block)", "dev.inmo.micro_utils.coroutines.launchWeak")) fun CoroutineScope.weakLaunch( context: CoroutineContext = EmptyCoroutineContext, diff --git a/coroutines/src/commonTest/kotlin/WeakJobTests.kt b/coroutines/src/commonTest/kotlin/WeakJobTests.kt index 69a0ffb463e..0a973465896 100644 --- a/coroutines/src/commonTest/kotlin/WeakJobTests.kt +++ b/coroutines/src/commonTest/kotlin/WeakJobTests.kt @@ -1,9 +1,6 @@ import dev.inmo.micro_utils.coroutines.asyncWeak import dev.inmo.micro_utils.coroutines.launchWeak -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertTrue @@ -33,4 +30,35 @@ class WeakJobTests { } error("Cancellation exception has not been thrown") } + @Test + fun testThatWeakJobsWorksCorrectly() = runTest { + val scope = CoroutineScope(Dispatchers.Default) + lateinit var weakLaunchJob: Job + lateinit var weakAsyncJob: Job + val completeDeferred = Job() + coroutineScope { + weakLaunchJob = launchWeak { + while (isActive) { + delay(100L) + } + } + weakAsyncJob = asyncWeak { + while (isActive) { + delay(100L) + } + } + + coroutineContext.job.invokeOnCompletion { + scope.launch { + delay(1000L) + completeDeferred.complete() + } + } + launch { delay(1000L); cancel() } + } + completeDeferred.join() + + assertTrue(!weakLaunchJob.isActive) + assertTrue(!weakAsyncJob.isActive) + } } \ No newline at end of file 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 deleted file mode 100644 index 311b3b05b3b..00000000000 --- a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/WeakJob.kt +++ /dev/null @@ -1,40 +0,0 @@ -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) - } -}