func (m *FairMix) runSource(closed chan struct{}, s *mixSource) {
defer m.wg.Done()
defer close(s.next)
for s.it.Next() {
n := s.it.Node()
fmt.Println("discmix Addsource : ", n.ID())
select {
case s.next <- n:
fmt.Println("s.next <- n :", n.ID())
case m.fromAny <- n:
fmt.Println("m.fromAny <- n :", n.ID())
case <-closed:
return
}
}
}
This is the Ethereum geth 1.9.25v code.
In the select
operation, these two s.next
& m.fromAny
variables both are waiting for n
.
But when I run the program, case s.next <- n
is being picked more frequently in comparison to case m.fromAny <- n
.
Can I know which case would be selected first? Is there some algorithm of picking the cases if multiple cases are ready?
I'd recommend you the Go Tour. In Go Tour, they have easy to understand hands-on playground where they covered the behavior of select
as well.
Link to Go Tour on select
So, a select
blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.
And, it's not just about n
but also about s.next
and m.fromAny
.
So, let's consider these two cases:
// For this case to be selected s.next should be ready
case s.next <- n
// For this case to be selected m.fromAny should be ready
case m.fromAny <- n
So, suppose s.next
and m.fromAny
both are ready at the same time, any case could be selected at random (described in the definition as well).
n
is available, so it depends on the receiver channels: s.next
and m.fromAny
.
Hence, we can't decide for sure which case would be selected if multiple are ready.