Reputation: 16174
I am a Go rookie.
I'm looking at this construct:
for {
select {
case <-resyncCh:
case <-stopCh:
return
case <-cancelCh:
return
}
if r.ShouldResync == nil || r.ShouldResync() {
// do stuff
}
resyncCh = r.resyncChan()
}
for
loop runs forever.break
is implicit in Go.select
statement are blocking if there's no default
clause (which there isn't here).Suppose resyncCh
does not have a message on it.
Are all the case
s evaluated (blocked on) in parallel? Or is there another path through this I'm not seeing?
I read this as:
resyncCh
, the stopCh
and the cancelCh
chan
s in parallel waiting for messagesresyncCh
, we effectively fall through to the r.ShouldResync
stuff, but the other blocks on the other chan
s remain.stopCh
or the cancelCh
chan
, return, effectively "disconnecting" from all chan
s here.Is that correct?
Upvotes: 2
Views: 2147
Reputation: 3293
In direct answer to your questions:
Block on the resyncCh, the stopCh and the cancelCh chans in parallel waiting for messages. YES.
If a message is received on resyncCh, we effectively fall through to the r.ShouldResync stuff, but the other blocks on the other chans remain. No, they don't remain, you are past the select
However, since this loops, you will block again. You could also use the fallthrough
keyword to make them block after passing the initial one.
If a message is received at any point on either the stopCh or the cancelCh chan, return, effectively "disconnecting" from all chans here. Correct - they would return from this function.
Also, bear in mind what you can do with a default
--> https://gobyexample.com/non-blocking-channel-operations
for {
select {
case <-resyncCh:
case <-stopCh:
return
case <-cancelCh:
return
default:
fmt.Printf("will keep printing\n")
}
if r.ShouldResync == nil || r.ShouldResync() {
// do stuff
}
resyncCh = r.resyncChan()
}
update: Another useful pattern, I'm using right now, which takes advantage of this:
select {
case m := <-c:
handle(m)
case <-time.After(5 * time.Minute):
fmt.Println("timed out")
}
Here you can wait, blocking, on a channel, but eventually timeout, just using the golang time
package. Very succinct and easy to read. Compare that to poll()
with timespec
values.
https://golang.org/pkg/time/#After
Upvotes: 2
Reputation: 12845
select
takes first not blocked action and goes to next operation.
Block on the resyncCh, the stopCh and the cancelCh chans in parallel waiting for messages
Yes, waiting for first of them.
If a message is received on resyncCh, we effectively fall through to the r.ShouldResync stuff, but the other blocks on the other chans remain.
Unlike in some other languages fallthrough is explicit in go - you should state it.
If a message is received at any point on either the stopCh or the cancelCh chan, return, effectively "disconnecting" from all chans here.
Exit from the function where the code located. Yes, we do not wait for new messages more.
Upvotes: 1