From df8809d30f6dc86e0bd7d1bb6d0b74694019e3d6 Mon Sep 17 00:00:00 2001 From: Vsevolod Tolstopyatov Date: Mon, 27 Feb 2023 17:18:49 +0100 Subject: [PATCH 1/2] Deprecate BroadcastChannel and the corresponding API Fixes #2680 --- .../common/src/channels/Broadcast.kt | 16 +++++++------- .../common/src/channels/BroadcastChannel.kt | 21 ++++++++++--------- .../common/src/channels/Channels.common.kt | 15 ++++++------- .../common/src/flow/Channels.kt | 3 ++- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/kotlinx-coroutines-core/common/src/channels/Broadcast.kt b/kotlinx-coroutines-core/common/src/channels/Broadcast.kt index 0a76c82f6a..e7a58ccdc4 100644 --- a/kotlinx-coroutines-core/common/src/channels/Broadcast.kt +++ b/kotlinx-coroutines-core/common/src/channels/Broadcast.kt @@ -2,6 +2,8 @@ * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ +@file:Suppress("DEPRECATION") + package kotlinx.coroutines.channels import kotlinx.coroutines.* @@ -35,13 +37,13 @@ import kotlin.coroutines.intrinsics.* * [send][BroadcastChannel.send] and [close][BroadcastChannel.close] operations that interfere with * the broadcasting coroutine in hard-to-specify ways. * - * **Note: This API is obsolete since 1.5.0.** It will be deprecated with warning in 1.6.0 - * and with error in 1.7.0. It is replaced with [Flow.shareIn][kotlinx.coroutines.flow.shareIn] - * operator. + * **Note: This API is obsolete since 1.5.0.** It is deprecated with warning in 1.7.0. + * It is replaced with [Flow.shareIn][kotlinx.coroutines.flow.shareIn] operator. * * @param start coroutine start option. The default value is [CoroutineStart.LAZY]. */ @ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public fun ReceiveChannel.broadcast( capacity: Int = 1, start: CoroutineStart = CoroutineStart.LAZY @@ -98,12 +100,11 @@ public fun ReceiveChannel.broadcast( * * ### Future replacement * - * This API is obsolete since 1.5.0. + * This API is obsolete since 1.5.0 and deprecated with warning since 1.7.0. * This function has an inappropriate result type of [BroadcastChannel] which provides * [send][BroadcastChannel.send] and [close][BroadcastChannel.close] operations that interfere with - * the broadcasting coroutine in hard-to-specify ways. It will be deprecated with warning in 1.6.0 - * and with error in 1.7.0. It is replaced with [Flow.shareIn][kotlinx.coroutines.flow.shareIn] - * operator. + * the broadcasting coroutine in hard-to-specify ways. + * It is replaced with [Flow.shareIn][kotlinx.coroutines.flow.shareIn] operator. * * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine. * @param capacity capacity of the channel's buffer (1 by default). @@ -112,6 +113,7 @@ public fun ReceiveChannel.broadcast( * @param block the coroutine code. */ @ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public fun CoroutineScope.broadcast( context: CoroutineContext = EmptyCoroutineContext, capacity: Int = 1, diff --git a/kotlinx-coroutines-core/common/src/channels/BroadcastChannel.kt b/kotlinx-coroutines-core/common/src/channels/BroadcastChannel.kt index de67b60a2d..e3c3a30666 100644 --- a/kotlinx-coroutines-core/common/src/channels/BroadcastChannel.kt +++ b/kotlinx-coroutines-core/common/src/channels/BroadcastChannel.kt @@ -2,7 +2,7 @@ * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -@file:Suppress("FunctionName") +@file:Suppress("FunctionName", "DEPRECATION") package kotlinx.coroutines.channels @@ -24,10 +24,11 @@ import kotlin.native.concurrent.* * See `BroadcastChannel()` factory function for the description of available * broadcast channel implementations. * - * **Note: This API is obsolete since 1.5.0.** It will be deprecated with warning in 1.6.0 - * and with error in 1.7.0. It is replaced with [SharedFlow][kotlinx.coroutines.flow.SharedFlow]. + * **Note: This API is obsolete since 1.5.0 and deprecated for removal since 1.7.0** + * It is replaced with [SharedFlow][kotlinx.coroutines.flow.SharedFlow]. */ @ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public interface BroadcastChannel : SendChannel { /** * Subscribes to this [BroadcastChannel] and returns a channel to receive elements from it. @@ -64,11 +65,11 @@ public interface BroadcastChannel : SendChannel { * * when `capacity` is [BUFFERED] -- creates `ArrayBroadcastChannel` with a default capacity. * * otherwise -- throws [IllegalArgumentException]. * - * **Note: This API is obsolete since 1.5.0.** It will be deprecated with warning in 1.6.0 - * and with error in 1.7.0. It is replaced with [StateFlow][kotlinx.coroutines.flow.StateFlow] - * and [SharedFlow][kotlinx.coroutines.flow.SharedFlow]. + * **Note: This API is obsolete since 1.5.0 and deprecated for removal since 1.7.0** + * It is replaced with [SharedFlow][kotlinx.coroutines.flow.SharedFlow] and [StateFlow][kotlinx.coroutines.flow.StateFlow]. */ @ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and StateFlow, and is no longer supported") public fun BroadcastChannel(capacity: Int): BroadcastChannel = when (capacity) { 0 -> throw IllegalArgumentException("Unsupported 0 capacity for BroadcastChannel") @@ -92,10 +93,11 @@ public fun BroadcastChannel(capacity: Int): BroadcastChannel = * In this implementation, [opening][openSubscription] and [closing][ReceiveChannel.cancel] subscription * takes linear time in the number of subscribers. * - * **Note: This API is obsolete since 1.5.0.** It will be deprecated with warning in 1.7.0 - * and with error in 1.8.0. It is replaced with [StateFlow][kotlinx.coroutines.flow.StateFlow]. + * **Note: This API is obsolete since 1.5.0 and deprecated for removal since 1.7.0** + * It is replaced with [SharedFlow][kotlinx.coroutines.flow.StateFlow]. */ @ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "ConflatedBroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public class ConflatedBroadcastChannel private constructor( private val broadcast: BroadcastChannelImpl ) : BroadcastChannel by broadcast { @@ -408,5 +410,4 @@ internal class BroadcastChannelImpl( "SUBSCRIBERS=${subscribers.joinToString(separator = ";", prefix = "<", postfix = ">")}" } -@SharedImmutable -private val NO_ELEMENT = Symbol("NO_ELEMENT") \ No newline at end of file +private val NO_ELEMENT = Symbol("NO_ELEMENT") diff --git a/kotlinx-coroutines-core/common/src/channels/Channels.common.kt b/kotlinx-coroutines-core/common/src/channels/Channels.common.kt index ac2e4cf6f0..606d2786ea 100644 --- a/kotlinx-coroutines-core/common/src/channels/Channels.common.kt +++ b/kotlinx-coroutines-core/common/src/channels/Channels.common.kt @@ -3,7 +3,7 @@ */ @file:JvmMultifileClass @file:JvmName("ChannelsKt") -@file:Suppress("DEPRECATION_ERROR") +@file:Suppress("DEPRECATION_ERROR", "DEPRECATION") @file:OptIn(ExperimentalContracts::class) package kotlinx.coroutines.channels @@ -22,10 +22,13 @@ internal const val DEFAULT_CLOSE_MESSAGE = "Channel was closed" * Opens subscription to this [BroadcastChannel] and makes sure that the given [block] consumes all elements * from it by always invoking [cancel][ReceiveChannel.cancel] after the execution of the block. * - * **Note: This API will become obsolete in future updates with introduction of lazy asynchronous streams.** - * See [issue #254](https://github.com/Kotlin/kotlinx.coroutines/issues/254). + * **Note: This API is obsolete since 1.5.0 and deprecated for removal since 1.7.0** + * It is replaced with [SharedFlow][kotlinx.coroutines.flow.SharedFlow]. + * + * Safe to remove in 1.9.0 as was inline before. */ @ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public inline fun BroadcastChannel.consume(block: ReceiveChannel.() -> R): R { val channel = openSubscription() try { @@ -107,7 +110,6 @@ public suspend inline fun ReceiveChannel.consumeEach(action: (E) -> Unit) * The operation is _terminal_. * This function [consumes][ReceiveChannel.consume] all elements of the original [ReceiveChannel]. */ -@OptIn(ExperimentalStdlibApi::class) public suspend fun ReceiveChannel.toList(): List = buildList { consumeEach { add(it) @@ -117,10 +119,9 @@ public suspend fun ReceiveChannel.toList(): List = buildList { /** * Subscribes to this [BroadcastChannel] and performs the specified action for each received element. * - * **Note: This API will become obsolete in future updates with introduction of lazy asynchronous streams.** - * See [issue #254](https://github.com/Kotlin/kotlinx.coroutines/issues/254). + * **Note: This API is obsolete since 1.5.0 and deprecated for removal since 1.7.0** */ -@ObsoleteCoroutinesApi +@Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public suspend inline fun BroadcastChannel.consumeEach(action: (E) -> Unit): Unit = consume { for (element in this) action(element) diff --git a/kotlinx-coroutines-core/common/src/flow/Channels.kt b/kotlinx-coroutines-core/common/src/flow/Channels.kt index 3da0780fe7..289d2ea966 100644 --- a/kotlinx-coroutines-core/common/src/flow/Channels.kt +++ b/kotlinx-coroutines-core/common/src/flow/Channels.kt @@ -144,11 +144,12 @@ private class ChannelAsFlow( * 2) Flow consumer completes normally when the original channel completes (~is closed) normally. * 3) If the flow consumer fails with an exception, subscription is cancelled. */ +@Suppress("DEPRECATION") @Deprecated( level = DeprecationLevel.WARNING, message = "'BroadcastChannel' is obsolete and all corresponding operators are deprecated " + "in the favour of StateFlow and SharedFlow" -) // Since 1.5.0, was @FlowPreview, safe to remove in 1.7.0 +) // Since 1.5.0, was @FlowPreview, safe to remove in 1.8.0 public fun BroadcastChannel.asFlow(): Flow = flow { emitAll(openSubscription()) } From be9337a69bc16b23723cac2ff658a417556fab08 Mon Sep 17 00:00:00 2001 From: Vsevolod Tolstopyatov Date: Fri, 3 Mar 2023 11:26:49 +0100 Subject: [PATCH 2/2] ~ --- .../common/src/channels/Channels.common.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kotlinx-coroutines-core/common/src/channels/Channels.common.kt b/kotlinx-coroutines-core/common/src/channels/Channels.common.kt index 606d2786ea..6ff3b385e4 100644 --- a/kotlinx-coroutines-core/common/src/channels/Channels.common.kt +++ b/kotlinx-coroutines-core/common/src/channels/Channels.common.kt @@ -3,7 +3,6 @@ */ @file:JvmMultifileClass @file:JvmName("ChannelsKt") -@file:Suppress("DEPRECATION_ERROR", "DEPRECATION") @file:OptIn(ExperimentalContracts::class) package kotlinx.coroutines.channels @@ -28,6 +27,7 @@ internal const val DEFAULT_CLOSE_MESSAGE = "Channel was closed" * Safe to remove in 1.9.0 as was inline before. */ @ObsoleteCoroutinesApi +@Suppress("DEPRECATION") @Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") public inline fun BroadcastChannel.consume(block: ReceiveChannel.() -> R): R { val channel = openSubscription() @@ -54,7 +54,7 @@ public inline fun BroadcastChannel.consume(block: ReceiveChannel.() ReplaceWith("receiveCatching().getOrNull()"), DeprecationLevel.ERROR ) // Warning since 1.5.0, ERROR in 1.6.0, HIDDEN in 1.7.0 -@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "DEPRECATION_ERROR") public suspend fun ReceiveChannel.receiveOrNull(): E? { return (this as ReceiveChannel).receiveOrNull() } @@ -66,6 +66,7 @@ public suspend fun ReceiveChannel.receiveOrNull(): E? { "Deprecated in the favour of 'onReceiveCatching'", level = DeprecationLevel.ERROR ) // Warning since 1.5.0, ERROR in 1.6.0, HIDDEN in 1.7.0 +@Suppress("DEPRECATION_ERROR") public fun ReceiveChannel.onReceiveOrNull(): SelectClause1 { return (this as ReceiveChannel).onReceiveOrNull } @@ -122,6 +123,7 @@ public suspend fun ReceiveChannel.toList(): List = buildList { * **Note: This API is obsolete since 1.5.0 and deprecated for removal since 1.7.0** */ @Deprecated(level = DeprecationLevel.WARNING, message = "BroadcastChannel is deprecated in the favour of SharedFlow and is no longer supported") +@Suppress("DEPRECATION") public suspend inline fun BroadcastChannel.consumeEach(action: (E) -> Unit): Unit = consume { for (element in this) action(element)