@@ -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.
@@ -125,7 +108,7 @@ public interface SendChannel<in E> {
125
108
* ```
126
109
* val events = Channel(UNLIMITED)
127
110
* callbackBasedApi.registerCallback { event ->
128
- * events.offer (event)
111
+ * events.trySend (event)
129
112
* }
130
113
*
131
114
* val uiUpdater = launch(Dispatchers.Main, parent = UILifecycle) {
@@ -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
+ )
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
/* *
@@ -544,14 +554,14 @@ public interface ChannelIterator<out E> {
544
554
*
545
555
* * When `capacity` is [Channel.UNLIMITED] — it creates a channel with effectively unlimited buffer.
546
556
* 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` .
557
+ * [Sending][send] to this channel never suspends, and [trySend ] always succeeds .
548
558
*
549
559
* * 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,
560
+ * This channel buffers at most one element and conflates all subsequent `send` and `trySend ` invocations,
551
561
* so that the receiver always gets the last element sent.
552
562
* Back-to-back sent elements are conflated — only the last sent element is received,
553
563
* while previously sent elements **are lost**.
554
- * [Sending][send] to this channel never suspends, and [offer ] always returns `true` .
564
+ * [Sending][send] to this channel never suspends, and [trySend ] always succeeds .
555
565
*
556
566
* * When `capacity` is positive but less than [UNLIMITED] — it creates an array-based channel with the specified capacity.
557
567
* This channel has an array buffer of a fixed `capacity`.
@@ -598,8 +608,6 @@ public interface ChannelIterator<out E> {
598
608
*
599
609
* * When [send][SendChannel.send] operation throws an exception because it was cancelled before it had a chance to actually
600
610
* 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
611
* * When [receive][ReceiveChannel.receive], [receiveOrNull][ReceiveChannel.receiveOrNull], or [hasNext][ChannelIterator.hasNext]
604
612
* operation throws an exception when it had retrieved the element from the
605
613
* channel but was cancelled before the code following the receive call resumed.
0 commit comments