# \[coroutines\] Can channel lose messages if receive() was cancelled?

**URL:** <https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820>\
**Category:** Support\
**Created:** [October 12, 2018, 12:50pm UTC](https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820 "2018-10-12T12:50:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![anti-social](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/anti-social/32/5555_2.png) [@anti-social](https://discuss.kotlinlang.org/u/anti-social)\
**Post date:** [October 12, 2018, 12:50pm UTC](https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820/1 "2018-10-12T12:50:07Z")

</div>

I have an actor that calls `receive()` inside `withTimeoutOrNull` block. And sometimes messages that was sent into the channel is lost. This happens after timeout was raised.

[Channel.receive documentation](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-receive-channel/receive.html) says:

> _Cancellation of suspended receive is atomic_ – when this function throws [CancellationException](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-cancellation-exception/index.html) it means that the element was not retrieved from this channel.

So I think `receive()` should not lose messages.  
Or there is a bug in my code.

There is an example project:

> **[GitHub - anti-social/channel-with-timeout](https://github.com/anti-social/channel-with-timeout)**
>
> Contribute to anti-social/channel-with-timeout development by creating an account on GitHub.

And when I run `./gradlew jcstress` I got a lot of errors like next:

```
[FAILED] channel.ChannelWithTimeoutStressTest                                                                                                      
  (fork: #1, iteration #1, JVM args: [-XX:+UnlockDiagnosticVMOptions, -XX:+WhiteBoxAPI, -XX:-RestrictContended, -Dfile.encoding=UTF-8, -Duser.country=UA, -Duser.language=en, -Duser.variant, -XX:TieredStopAtLevel=1])
Observed state Occurrences Expectation Interpretation                                              
             0 39 ACCEPTABLE OK                                                          
             1 1 FORBIDDEN Message was lost

```

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [October 13, 2018, 8:59am UTC](https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820/2 "2018-10-13T08:59:19Z")

</div>

`withTimeoutOrNull` that you are using does not have the property of atomic cancellation, hence lost messages.

---

<div class="post-metadata">

**Author:** ![anti-social](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/anti-social/32/5555_2.png) [@anti-social](https://discuss.kotlinlang.org/u/anti-social)\
**Post date:** [October 15, 2018, 11:37am UTC](https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820/3 "2018-10-15T11:37:48Z")

</div>

Think such a behaviour is unclear. It should be properly indicated in the documentation. At the moment `withTimeout` and `withTimeoutOrNull` have almost identical description from which it may seem that `withTimeoutOrNull` is just a wrapper. It may be misleading.

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [October 15, 2018, 12:06pm UTC](https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820/4 "2018-10-15T12:06:47Z")

</div>

withTimeout is not atomic either. Currently, only suspending functions that have explicit mention of “atomic cancellation” in their documentation provide this property of atomic cancellation.

---

<div class="post-metadata">

**Author:** ![anti-social](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/anti-social/32/5555_2.png) [@anti-social](https://discuss.kotlinlang.org/u/anti-social)\
**Post date:** [October 16, 2018, 1:49am UTC](https://discuss.kotlinlang.org/t/coroutines-can-channel-lose-messages-if-receive-was-cancelled/9820/5 "2018-10-16T01:49:54Z")

</div>

I’ve just tried to use `select` with `onTimeout` clause and it works fine.

IMHO it is really counterintuitive that `withTimeout` throws away result of a single operation which is atomically cancellable, making next code is broken:

```
withTimeout(1) {
    channel.receive()
}

```

Thanks for the help.
