Case or default argument precedence in golang select statements

I have an application with several goroutines that work with loops for

and you need a way to signal those loops for

to break and check if a timeout has occurred. I was looking into using a shared pipe with operators select

to accomplish it like this:

// elsewhere in the code, this channel is created, and passed below
done := make(chan struct{})
time.AfterFunc(timeout, func() { close(done) })
...
go func() {
Loop:
  for {
    select {
    case <-done:
      break Loop
    default:
      foo()
      time.Sleep(1 * time.Second)
    }
  }
  select {
  case <-done:
    panic("timed out!")
  default:
    // ok
  }
}()

      

Is this the correct way to do this? My biggest concern is that the selected branch a select

might be non-deterministic, so you default

can choose even if one is case

ready. Is it possible? Is there any documentation that says conformance case

will take precedence over default

. The problem is that the loop above can run multiple times after the done

report closes and / or succeeds, even if the timeout has occurred.

+3


source to share


1 answer


Go programming language specification

Select statements

The "select" statement is executed in several stages:

  • For all cases in the instruction, the channel operands of the receive operations and the channel and right send expressions are evaluated exactly once, in the original order, after the "select" expression is entered. The result is a set of channels to receive from or send, and the corresponding values ​​to send. Either side effects in this evaluation will occur regardless of what (if any) the link operation is selected to proceed. Expressions on the left side of RecvStmt with a short variable declaration or assignment have not yet been evaluated.
  • If one or more messages can continue, one that can continue is selected through a uniform pseudo-random selection. Otherwise, if there is a default case, that case is selected. If this is not the standard case, the "select" statement blocks, at least one message can continue.
  • If the selected case is not the default case, the corresponding communication operation is performed.
  • If the selected case is a RecvStmt with a short variable declaration or assignment, the left expressions are evaluated and assigned the accepted value (s).
  • The list of operators of the selected case is executed.



"What worries me most is that the selection branch that is selected may be non-deterministic, so that the default can be selected even if one of the cases is ready. Is that possible?"

Not. See Step 2 of the specification select

.

+6


source







All Articles