1

Assume the following snippet:

for {
    select {
    case val := <-chan:
        doSomething(ctx, val)
    case <-ctx.Done():
        return
    }
}

There could be a scenario where the context was canceled, but the select case still chooses the first case if the channel has messages in it. Resulting in calling doSomething with a canceled context.

A solution could be:

for {
    select {
    case val := <-chan:
        select {
        case <-ctx.Done():
            return
        default:
            doSomething(ctx, val)
        }
    case <-ctx.Done():
        return
    }
}

This would work, but it feels wrong.

Is there another cleaner way to achieve the same behavior?

GuD
  • 668
  • 5
  • 9
  • 1
    if you call doSomething with a cancelled context, it should do nothing, right? Since thats the point of passing the context in the first place. – The Fool Apr 05 '22 at 10:39
  • Do a non-blocking check of the `done` channel first if you don't want to execute / process the other communication op if the `done` channel is already closed. – icza Apr 05 '22 at 11:02

0 Answers0