Skip to content
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

Context Cancellation Select #105

Open
FarhanSajid1 opened this issue Oct 24, 2024 · 0 comments
Open

Context Cancellation Select #105

FarhanSajid1 opened this issue Oct 24, 2024 · 0 comments
Labels
community mistake Mistakes proposed by the community

Comments

@FarhanSajid1
Copy link

Describe the mistake

In section 8.6.4 "catching a context cancellation", we have the following solution for handling a context cancellation prior to reading/writing from a channel


func f(ctx context.Context) error {
    // ...
    select {
    case <-ctx.Done():
        return ctx.Err()
    case ch1 <- struct{}{}:
    }
    select {
    case <-ctx.Done():
        return ctx.Err()
    case v := <-ch2:
// ... }
}

Essentially, check if the context is done prior to reading/writing.

This is contradicted by mistake #64 (Expecting deterministic behavior using select and channels)

Which goes into detail about this

_If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.
_

Given that, we cannot use the following approach, what if both are able to be read, the go runtime will choose one at random and that could potentially block?

Solution

I've seen the following solution, it's not the best, but it should work

    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {            
        //select as usual
        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            //give priority to a possible concurrent Done() event non-blocking way
            select {
              case <-ctx.Done():
              return
            default:
            }
            sendHeartbeat()
        }
    }

As outlined here: https://stackoverflow.com/a/51296312

@FarhanSajid1 FarhanSajid1 added the community mistake Mistakes proposed by the community label Oct 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community mistake Mistakes proposed by the community
Projects
None yet
Development

No branches or pull requests

1 participant