Skip to content

Commit 91e1848

Browse files
committed
Deprecate SendChannel.isFull and ReceiveChannel.isEmpty properties
Fixes #1053
1 parent ac136d6 commit 91e1848

File tree

5 files changed

+28
-30
lines changed

5 files changed

+28
-30
lines changed

kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt

+7-5
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
167167
// ------ SendChannel ------
168168

169169
public final override val isClosedForSend: Boolean get() = closedForSend != null
170-
public final override val isFull: Boolean get() = queue.nextNode !is ReceiveOrClosed<*> && isBufferFull
170+
public final override val isFull: Boolean get() = full
171+
private val full: Boolean get() = queue.nextNode !is ReceiveOrClosed<*> && isBufferFull // TODO rename to `isFull`
171172

172173
public final override suspend fun send(element: E) {
173174
// fast path -- try offer non-blocking
@@ -402,7 +403,7 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
402403
private fun <R> registerSelectSend(select: SelectInstance<R>, element: E, block: suspend (SendChannel<E>) -> R) {
403404
while (true) {
404405
if (select.isSelected) return
405-
if (isFull) {
406+
if (full) {
406407
val enqueueOp = TryEnqueueSendDesc(element, select, block)
407408
val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return
408409
when {
@@ -561,7 +562,8 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
561562
// ------ ReceiveChannel ------
562563

563564
public final override val isClosedForReceive: Boolean get() = closedForReceive != null && isBufferEmpty
564-
public final override val isEmpty: Boolean get() = queue.nextNode !is Send && isBufferEmpty
565+
public final override val isEmpty: Boolean get() = empty
566+
private val empty: Boolean get() = queue.nextNode !is Send && isBufferEmpty // TODO rename to `isEmpty`
565567

566568
@Suppress("UNCHECKED_CAST")
567569
public final override suspend fun receive(): E {
@@ -748,7 +750,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
748750
private fun <R> registerSelectReceive(select: SelectInstance<R>, block: suspend (E) -> R) {
749751
while (true) {
750752
if (select.isSelected) return
751-
if (isEmpty) {
753+
if (empty) {
752754
val enqueueOp = TryEnqueueReceiveDesc(select, block as (suspend (E?) -> R), nullOnClose = false)
753755
val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return
754756
when {
@@ -782,7 +784,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
782784
private fun <R> registerSelectReceiveOrNull(select: SelectInstance<R>, block: suspend (E?) -> R) {
783785
while (true) {
784786
if (select.isSelected) return
785-
if (isEmpty) {
787+
if (empty) {
786788
val enqueueOp = TryEnqueueReceiveDesc(select, block, nullOnClose = true)
787789
val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return
788790
when {

kotlinx-coroutines-core/common/src/channels/Channel.kt

+12-11
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ public interface SendChannel<in E> {
3030
* Returns `true` if the channel is full (out of capacity) and the [send] attempt will suspend.
3131
* This function returns `false` for [isClosedForSend] channel.
3232
*
33-
* **Note: This is an experimental api.** This property may change its semantics and/or name in the future.
33+
* @suppress **Will be removed in next releases, no replacement.**
3434
*/
3535
@ExperimentalCoroutinesApi
36+
@Deprecated(level = DeprecationLevel.ERROR, message = "Will be removed in next releases without replacement")
3637
public val isFull: Boolean
3738

3839
/**
39-
* Adds [element] into to this channel, suspending the caller while this channel [isFull],
40-
* or throws exception if the channel [isClosedForSend] (see [close] for details).
40+
* Adds [element] into to this channel, suspending the caller while the buffer of this channel is full
41+
* or if it does not exist, or throws exception if the channel [isClosedForSend] (see [close] for details).
4142
*
4243
* Note, that closing a channel _after_ this function had suspended does not cause this suspended send invocation
4344
* to abort, because closing a channel is conceptually like sending a special "close token" over this channel.
@@ -151,13 +152,14 @@ public interface ReceiveChannel<out E> {
151152
* Returns `true` if the channel is empty (contains no elements) and the [receive] attempt will suspend.
152153
* This function returns `false` for [isClosedForReceive] channel.
153154
*
154-
* **Note: This is an experimental api.** This property may change its semantics and/or name in the future.
155+
* @suppress **Will be removed in next releases, no replacement.**
155156
*/
156157
@ExperimentalCoroutinesApi
158+
@Deprecated(level = DeprecationLevel.ERROR, message = "Will be removed in next releases without replacement")
157159
public val isEmpty: Boolean
158160

159161
/**
160-
* Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty]
162+
* Retrieves and removes the element from this channel suspending the caller while this channel is empty,
161163
* or throws [ClosedReceiveChannelException] if the channel [isClosedForReceive].
162164
* If the channel was closed because of the exception, it is called a _failed_ channel and this function
163165
* throws the original [close][SendChannel.close] cause exception.
@@ -188,7 +190,7 @@ public interface ReceiveChannel<out E> {
188190
public val onReceive: SelectClause1<E>
189191

190192
/**
191-
* Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty]
193+
* Retrieves and removes the element from this channel suspending the caller while this channel is empty,
192194
* or returns `null` if the channel is [closed][isClosedForReceive] without cause
193195
* or throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
194196
*
@@ -227,7 +229,7 @@ public interface ReceiveChannel<out E> {
227229
public val onReceiveOrNull: SelectClause1<E?>
228230

229231
/**
230-
* Retrieves and removes the element from this channel, or returns `null` if this channel [isEmpty]
232+
* Retrieves and removes the element from this channel, or returns `null` if this channel is empty
231233
* or is [isClosedForReceive] without cause.
232234
* It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
233235
*/
@@ -273,9 +275,8 @@ public interface ReceiveChannel<out E> {
273275
*/
274276
public interface ChannelIterator<out E> {
275277
/**
276-
* Returns `true` if the channel has more elements suspending the caller while this channel
277-
* [isEmpty][ReceiveChannel.isEmpty] or returns `false` if the channel
278-
* [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause.
278+
* Returns `true` if the channel has more elements, suspending the caller while this channel is empty,
279+
* or returns `false` if the channel [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause.
279280
* It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
280281
*
281282
* This function retrieves and removes the element from this channel for the subsequent invocation
@@ -297,7 +298,7 @@ public interface ChannelIterator<out E> {
297298

298299
/**
299300
* Retrieves and removes the element from this channel suspending the caller while this channel
300-
* [isEmpty][ReceiveChannel.isEmpty] or throws [ClosedReceiveChannelException] if the channel
301+
* is empty or throws [ClosedReceiveChannelException] if the channel
301302
* [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause.
302303
* It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
303304
*

kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt

+5-9
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ class ArrayChannelTest : TestBase() {
1111
@Test
1212
fun testSimple() = runTest {
1313
val q = Channel<Int>(1)
14-
check(q.isEmpty && !q.isFull)
1514
expect(1)
1615
val sender = launch {
1716
expect(4)
1817
q.send(1) // success -- buffered
19-
check(!q.isEmpty && q.isFull)
2018
expect(5)
2119
q.send(2) // suspends (buffer full)
2220
expect(9)
@@ -25,29 +23,27 @@ class ArrayChannelTest : TestBase() {
2523
val receiver = launch {
2624
expect(6)
2725
check(q.receive() == 1) // does not suspend -- took from buffer
28-
check(!q.isEmpty && q.isFull) // waiting sender's element moved to buffer
2926
expect(7)
3027
check(q.receive() == 2) // does not suspend (takes from sender)
3128
expect(8)
3229
}
3330
expect(3)
3431
sender.join()
3532
receiver.join()
36-
check(q.isEmpty && !q.isFull)
3733
finish(10)
3834
}
3935

4036
@Test
4137
fun testClosedBufferedReceiveOrNull() = runTest {
4238
val q = Channel<Int>(1)
43-
check(q.isEmpty && !q.isFull && !q.isClosedForSend && !q.isClosedForReceive)
39+
check(!q.isClosedForSend && !q.isClosedForReceive)
4440
expect(1)
4541
launch {
4642
expect(5)
47-
check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive)
43+
check(q.isClosedForSend && !q.isClosedForReceive)
4844
assertEquals(42, q.receiveOrNull())
4945
expect(6)
50-
check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
46+
check(q.isClosedForSend && q.isClosedForReceive)
5147
assertEquals(null, q.receiveOrNull())
5248
expect(7)
5349
}
@@ -56,9 +52,9 @@ class ArrayChannelTest : TestBase() {
5652
expect(3)
5753
q.close() // goes on
5854
expect(4)
59-
check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive)
55+
check(q.isClosedForSend && !q.isClosedForReceive)
6056
yield()
61-
check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
57+
check(q.isClosedForSend && q.isClosedForReceive)
6258
finish(8)
6359
}
6460

kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt

+3-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class RendezvousChannelTest : TestBase() {
1111
@Test
1212
fun testSimple() = runTest {
1313
val q = Channel<Int>(Channel.RENDEZVOUS)
14-
check(q.isEmpty && q.isFull)
1514
expect(1)
1615
val sender = launch {
1716
expect(4)
@@ -31,14 +30,13 @@ class RendezvousChannelTest : TestBase() {
3130
expect(3)
3231
sender.join()
3332
receiver.join()
34-
check(q.isEmpty && q.isFull)
3533
finish(10)
3634
}
3735

3836
@Test
3937
fun testClosedReceiveOrNull() = runTest {
4038
val q = Channel<Int>(Channel.RENDEZVOUS)
41-
check(q.isEmpty && q.isFull && !q.isClosedForSend && !q.isClosedForReceive)
39+
check(!q.isClosedForSend && !q.isClosedForReceive)
4240
expect(1)
4341
launch {
4442
expect(3)
@@ -51,9 +49,9 @@ class RendezvousChannelTest : TestBase() {
5149
q.send(42)
5250
expect(5)
5351
q.close()
54-
check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
52+
check(q.isClosedForSend && q.isClosedForReceive)
5553
yield()
56-
check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
54+
check(q.isClosedForSend && q.isClosedForReceive)
5755
finish(7)
5856
}
5957

kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ private class ChannelViaBroadcast<E>(
5454
val sub = broadcast.openSubscription()
5555

5656
override val isClosedForReceive: Boolean get() = sub.isClosedForReceive
57+
@Suppress("DEPRECATION_ERROR")
5758
override val isEmpty: Boolean get() = sub.isEmpty
5859

5960
override suspend fun receive(): E = sub.receive()

0 commit comments

Comments
 (0)