@@ -24,7 +24,7 @@ import kotlin.jvm.*
24
24
public interface SendChannel <in E > {
25
25
/* *
26
26
* Returns `true` if this channel was closed by an invocation of [close]. This means that
27
- * calling [send] or [offer] will result in an exception.
27
+ * calling [send] will result in an exception.
28
28
*
29
29
* **Note: This is an experimental api.** This property may change its semantics and/or name in the future.
30
30
*/
@@ -51,7 +51,7 @@ public interface SendChannel<in E> {
51
51
* Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed.
52
52
*
53
53
* This function can be used in [select] invocations with the [onSend] clause.
54
- * Use [offer ] to try sending to this channel without waiting.
54
+ * Use [trySend ] to try sending to this channel without waiting.
55
55
*/
56
56
public suspend fun send (element : E )
57
57
@@ -64,23 +64,6 @@ public interface SendChannel<in E> {
64
64
*/
65
65
public val onSend: SelectClause2 <E , SendChannel <E >>
66
66
67
- /* *
68
- * Immediately adds the specified [element] to this channel, if this doesn't violate its capacity restrictions,
69
- * and returns `true`. Otherwise, just returns `false`. This is a synchronous variant of [send] which backs off
70
- * in situations when `send` suspends.
71
- *
72
- * Throws an exception if the channel [is closed for `send`][isClosedForSend] (see [close] for details).
73
- *
74
- * When `offer` call returns `false` it guarantees that the element was not delivered to the consumer and it
75
- * it does not call `onUndeliveredElement` that was installed for this channel. If the channel was closed,
76
- * then it calls `onUndeliveredElement` before throwing an exception.
77
- * See "Undelivered elements" section in [Channel] documentation for details on handling undelivered elements.
78
- */
79
- public fun offer (element : E ): Boolean {
80
- val result = trySend(element)
81
- if (result.isSuccess) return true
82
- throw recoverStackTrace(result.exceptionOrNull() ? : return false )
83
- }
84
67
85
68
/* *
86
69
* Immediately adds the specified [element] to this channel, if this doesn't violate its capacity restrictions,
@@ -103,7 +86,7 @@ public interface SendChannel<in E> {
103
86
* on the side of [ReceiveChannel] starts returning `true` only after all previously sent elements
104
87
* are received.
105
88
*
106
- * A channel that was closed without a [cause] throws a [ClosedSendChannelException] on attempts to [send] or [offer]
89
+ * A channel that was closed without a [cause] throws a [ClosedSendChannelException] on attempts to [send]
107
90
* and [ClosedReceiveChannelException] on attempts to [receive][ReceiveChannel.receive].
108
91
* A channel that was closed with non-null [cause] is called a _failed_ channel. Attempts to send or
109
92
* receive on a failed channel throw the specified [cause] exception.
@@ -122,10 +105,11 @@ public interface SendChannel<in E> {
122
105
* * the cause of `close` or `cancel` otherwise.
123
106
*
124
107
* Example of usage (exception handling is omitted):
108
+ *
125
109
* ```
126
110
* val events = Channel(UNLIMITED)
127
111
* callbackBasedApi.registerCallback { event ->
128
- * events.offer (event)
112
+ * events.trySend (event)
129
113
* }
130
114
*
131
115
* val uiUpdater = launch(Dispatchers.Main, parent = UILifecycle) {
@@ -134,7 +118,6 @@ public interface SendChannel<in E> {
134
118
* }
135
119
*
136
120
* events.invokeOnClose { callbackBasedApi.stop() }
137
- *
138
121
* ```
139
122
*
140
123
* **Note: This is an experimental api.** This function may change its semantics, parameters or return type in the future.
@@ -146,6 +129,33 @@ public interface SendChannel<in E> {
146
129
*/
147
130
@ExperimentalCoroutinesApi
148
131
public fun invokeOnClose (handler : (cause: Throwable ? ) -> Unit )
132
+
133
+ /* *
134
+ * **Deprecated** offer method.
135
+ *
136
+ * This method was deprecated in the favour of [trySend].
137
+ * It has proven itself as the most error-prone method in Channel API:
138
+ *
139
+ * * `Boolean` return type creates the false sense of security, implying that `false`
140
+ * is returned instead of throwing an exception.
141
+ * * It was used mostly from non-suspending APIs where CancellationException triggered
142
+ * internal failures in the application (the most common source of bugs).
143
+ * * Due to signature and explicit `if (ch.offer(...))` checks it was easy to
144
+ * oversee such error during code review.
145
+ * * Its name was not aligned with the rest of the API and tried to mimic Java's queue instead.
146
+ *
147
+ * See https://github.com/Kotlin/kotlinx.coroutines/issues/974 for more context.
148
+ */
149
+ @Deprecated(
150
+ level = DeprecationLevel .WARNING ,
151
+ message = " Deprecated in the favour of 'trySend' method" ,
152
+ replaceWith = ReplaceWith (" trySend(element).isSuccess" )
153
+ ) // Since 1.5.0
154
+ public fun offer (element : E ): Boolean {
155
+ val result = trySend(element)
156
+ if (result.isSuccess) return true
157
+ throw recoverStackTrace(result.exceptionOrNull() ? : return false )
158
+ }
149
159
}
150
160
151
161
/* *
@@ -188,7 +198,7 @@ public interface ReceiveChannel<out E> {
188
198
* Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed.
189
199
*
190
200
* This function can be used in [select] invocations with the [onReceive] clause.
191
- * Use [poll ] to try receiving from this channel without waiting.
201
+ * Use [tryReceive ] to try receiving from this channel without waiting.
192
202
*/
193
203
public suspend fun receive (): E
194
204
@@ -200,51 +210,6 @@ public interface ReceiveChannel<out E> {
200
210
*/
201
211
public val onReceive: SelectClause1 <E >
202
212
203
- /* *
204
- * This function was deprecated since 1.3.0 and is no longer recommended to use
205
- * or to implement in subclasses.
206
- *
207
- * It had the following pitfalls:
208
- * - Didn't allow to distinguish 'null' as "closed channel" from "null as a value"
209
- * - Was throwing if the channel has failed even though its signature may suggest it returns 'null'
210
- * - It didn't really belong to core channel API and can be exposed as an extension instead.
211
- *
212
- * @suppress doc
213
- */
214
- @Suppress(" INVISIBLE_REFERENCE" , " INVISIBLE_MEMBER" )
215
- @LowPriorityInOverloadResolution
216
- @Deprecated(
217
- message = " Deprecated in favor of receiveCatching" ,
218
- level = DeprecationLevel .ERROR ,
219
- replaceWith = ReplaceWith (" receiveCatching().getOrNull()" )
220
- ) // Warning since 1.3.0, error in 1.5.0, will be hidden in 1.6.0
221
- public suspend fun receiveOrNull (): E ? = receiveCatching().getOrNull()
222
-
223
- /* *
224
- * This function was deprecated since 1.3.0 and is no longer recommended to use
225
- * or to implement in subclasses.
226
- * See [receiveOrNull] documentation.
227
- *
228
- * @suppress **Deprecated**: in favor of onReceiveCatching extension.
229
- */
230
- @Deprecated(
231
- message = " Deprecated in favor of onReceiveCatching extension" ,
232
- level = DeprecationLevel .ERROR ,
233
- replaceWith = ReplaceWith (" onReceiveCatching" )
234
- ) // Warning since 1.3.0, error in 1.5.0, will be hidden or removed in 1.6.0
235
- public val onReceiveOrNull: SelectClause1 <E ?>
236
- get() {
237
- return object : SelectClause1 <E ?> {
238
- @InternalCoroutinesApi
239
- override fun <R > registerSelectClause1 (select : SelectInstance <R >, block : suspend (E ? ) -> R ) {
240
- onReceiveCatching.registerSelectClause1(select) {
241
- it.exceptionOrNull()?.let { throw it }
242
- block(it.getOrNull())
243
- }
244
- }
245
- }
246
- }
247
-
248
213
/* *
249
214
* Retrieves and removes an element from this channel if it's not empty, or suspends the caller while this channel is empty.
250
215
* This method returns [ChannelResult] with the value of an element successfully retrieved from the channel
@@ -262,7 +227,7 @@ public interface ReceiveChannel<out E> {
262
227
* Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed.
263
228
*
264
229
* This function can be used in [select] invocations with the [onReceiveCatching] clause.
265
- * Use [poll ] to try receiving from this channel without waiting.
230
+ * Use [tryReceive ] to try receiving from this channel without waiting.
266
231
*/
267
232
public suspend fun receiveCatching (): ChannelResult <E >
268
233
@@ -273,17 +238,6 @@ public interface ReceiveChannel<out E> {
273
238
*/
274
239
public val onReceiveCatching: SelectClause1 <ChannelResult <E >>
275
240
276
- /* *
277
- * Retrieves and removes an element from this channel if it's not empty or returns `null` if the channel is empty
278
- * or is [is closed for `receive`][isClosedForReceive] without a cause.
279
- * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
280
- */
281
- public fun poll (): E ? {
282
- val result = tryReceive()
283
- if (result.isSuccess) return result.getOrThrow()
284
- throw recoverStackTrace(result.exceptionOrNull() ? : return null )
285
- }
286
-
287
241
/* *
288
242
* Retrieves and removes an element from this channel if it's not empty, returning a [successful][ChannelResult.success]
289
243
* result, returns [failed][ChannelResult.failed] result if the channel is empty, and [closed][ChannelResult.closed]
@@ -325,6 +279,75 @@ public interface ReceiveChannel<out E> {
325
279
*/
326
280
@Deprecated(level = DeprecationLevel .HIDDEN , message = " Since 1.2.0, binary compatibility with versions <= 1.1.x" )
327
281
public fun cancel (cause : Throwable ? = null): Boolean
282
+
283
+ /* *
284
+ * **Deprecated** poll method.
285
+ *
286
+ * This method was deprecated in the favour of [tryReceive].
287
+ * It has proven itself as error-prone method in Channel API:
288
+ *
289
+ * * Nullable return type creates the false sense of security, implying that `null`
290
+ * is returned instead of throwing an exception.
291
+ * * It was used mostly from non-suspending APIs where CancellationException triggered
292
+ * internal failures in the application (the most common source of bugs).
293
+ * * Its name was not aligned with the rest of the API and tried to mimic Java's queue instead.
294
+ *
295
+ * See https://github.com/Kotlin/kotlinx.coroutines/issues/974 for more context.
296
+ */
297
+ @Deprecated(level = DeprecationLevel .WARNING ,
298
+ message = " Deprecated in the favour of 'tryReceive'" ,
299
+ replaceWith = ReplaceWith (" tryReceive().getOrNull()" )
300
+ ) // Since 1.5.0
301
+ public fun poll (): E ? {
302
+ val result = tryReceive()
303
+ if (result.isSuccess) return result.getOrThrow()
304
+ throw recoverStackTrace(result.exceptionOrNull() ? : return null )
305
+ }
306
+
307
+ /* *
308
+ * This function was deprecated since 1.3.0 and is no longer recommended to use
309
+ * or to implement in subclasses.
310
+ *
311
+ * It had the following pitfalls:
312
+ * - Didn't allow to distinguish 'null' as "closed channel" from "null as a value"
313
+ * - Was throwing if the channel has failed even though its signature may suggest it returns 'null'
314
+ * - It didn't really belong to core channel API and can be exposed as an extension instead.
315
+ *
316
+ * @suppress doc
317
+ */
318
+ @Suppress(" INVISIBLE_REFERENCE" , " INVISIBLE_MEMBER" )
319
+ @LowPriorityInOverloadResolution
320
+ @Deprecated(
321
+ message = " Deprecated in favor of receiveCatching" ,
322
+ level = DeprecationLevel .ERROR ,
323
+ replaceWith = ReplaceWith (" receiveCatching().getOrNull()" )
324
+ ) // Warning since 1.3.0, error in 1.5.0, will be hidden in 1.6.0
325
+ public suspend fun receiveOrNull (): E ? = receiveCatching().getOrNull()
326
+
327
+ /* *
328
+ * This function was deprecated since 1.3.0 and is no longer recommended to use
329
+ * or to implement in subclasses.
330
+ * See [receiveOrNull] documentation.
331
+ *
332
+ * @suppress **Deprecated**: in favor of onReceiveCatching extension.
333
+ */
334
+ @Deprecated(
335
+ message = " Deprecated in favor of onReceiveCatching extension" ,
336
+ level = DeprecationLevel .ERROR ,
337
+ replaceWith = ReplaceWith (" onReceiveCatching" )
338
+ ) // Warning since 1.3.0, error in 1.5.0, will be hidden or removed in 1.6.0
339
+ public val onReceiveOrNull: SelectClause1 <E ?>
340
+ get() {
341
+ return object : SelectClause1 <E ?> {
342
+ @InternalCoroutinesApi
343
+ override fun <R > registerSelectClause1 (select : SelectInstance <R >, block : suspend (E ? ) -> R ) {
344
+ onReceiveCatching.registerSelectClause1(select) {
345
+ it.exceptionOrNull()?.let { throw it }
346
+ block(it.getOrNull())
347
+ }
348
+ }
349
+ }
350
+ }
328
351
}
329
352
330
353
/* *
@@ -544,14 +567,14 @@ public interface ChannelIterator<out E> {
544
567
*
545
568
* * When `capacity` is [Channel.UNLIMITED] — it creates a channel with effectively unlimited buffer.
546
569
* This channel has a linked-list buffer of unlimited capacity (limited only by available memory).
547
- * [Sending][send] to this channel never suspends, and [offer ] always returns `true` .
570
+ * [Sending][send] to this channel never suspends, and [trySend ] always succeeds .
548
571
*
549
572
* * When `capacity` is [Channel.CONFLATED] — it creates a _conflated_ channel
550
- * This channel buffers at most one element and conflates all subsequent `send` and `offer ` invocations,
573
+ * This channel buffers at most one element and conflates all subsequent `send` and `trySend ` invocations,
551
574
* so that the receiver always gets the last element sent.
552
575
* Back-to-back sent elements are conflated — only the last sent element is received,
553
576
* while previously sent elements **are lost**.
554
- * [Sending][send] to this channel never suspends, and [offer ] always returns `true` .
577
+ * [Sending][send] to this channel never suspends, and [trySend ] always succeeds .
555
578
*
556
579
* * When `capacity` is positive but less than [UNLIMITED] — it creates an array-based channel with the specified capacity.
557
580
* This channel has an array buffer of a fixed `capacity`.
@@ -598,8 +621,6 @@ public interface ChannelIterator<out E> {
598
621
*
599
622
* * When [send][SendChannel.send] operation throws an exception because it was cancelled before it had a chance to actually
600
623
* send the element or because the channel was [closed][SendChannel.close] or [cancelled][ReceiveChannel.cancel].
601
- * * When [offer][SendChannel.offer] operation throws an exception when
602
- * the channel was [closed][SendChannel.close] or [cancelled][ReceiveChannel.cancel].
603
624
* * When [receive][ReceiveChannel.receive], [receiveOrNull][ReceiveChannel.receiveOrNull], or [hasNext][ChannelIterator.hasNext]
604
625
* operation throws an exception when it had retrieved the element from the
605
626
* channel but was cancelled before the code following the receive call resumed.
0 commit comments