Search code examples
goethereumchannel

select case selection in geth 1.9.25v


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?


Solution

  • 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.