Skip to content

withTimeoutOrNull and channel send/receive #1355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
fvasco opened this issue Jul 19, 2019 · 4 comments
Closed

withTimeoutOrNull and channel send/receive #1355

fvasco opened this issue Jul 19, 2019 · 4 comments

Comments

@fvasco
Copy link
Contributor

fvasco commented Jul 19, 2019

Our server is affected by sporadic errors, these errors are not well defined and not reproducible.

I wrote a bad test case (#1281) some time ago, sorry, a have to file a new issue.

In our previous experience the major candidate is withTimeoutOrNull + channel.send, the in that case the coroutine hangs indefinitely.

The prevision version below worked without any issue

val delay = launch { delay(42) }
whileSelect {
    channel.onReceive {
        consume(it) // no suspension
        true
    }
    delay.onJoin { false }
}

Yesterday we get a similar issue, the code is:

withTimeoutOrNull(42){
    val value = channel.receive()
    consume(value) // no suspension
}

We suspect that a single value was extracted but not consumed.

Thoughts?

Edit: consume is not a suspending function

@elizarov
Copy link
Contributor

These particular code path are pretty well covered by functional and stress-tests and I wonder what might have gone wrong. Any chance for a reproducer?

@fvasco
Copy link
Contributor Author

fvasco commented Jul 19, 2019

Thank you for response @elizarov,
this is wonderful response.

I tried to reproduce this issue without any success.

In this particular case the consume function is list.add(value), I detected in production that one item was lost or was not processed.
Unfortunately there is no log to understand what exactly went wrong.

I will reopen this issue when further updates will be available.

Thank you again.

@fvasco fvasco closed this as completed Jul 19, 2019
@fvasco
Copy link
Contributor Author

fvasco commented Jul 21, 2019

I answer myself.

Thoughts?

Bug or not, chunking a channel using withTimeoutOrNull is probably a bad style of code: it mixes cancellable and non-cancellable blocks, additionally it works using the non cancellability of non-suspending function as a trick.

Using a selector is the way to go, maybe it is slower and harder to write, moreover it requires to cancel delay job manually (#1065), but it works always as expected.

@elizarov
Copy link
Contributor

Still it should work and pretty-well covered by tests....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants