goconcurrencychannelwaitgroup

In Go, how do we apply concurrency calls while preserving the order of the list?


To give you context,

The variable elementInput is dynamic. I do not know the exact length of it. It can be 10, 5, or etc.

The *Element channel type is struct

My example is working. But my problem is this implementation is still synchronized, because I am waiting for the channel return so that I can append it to my result

Can you pls help me how to concurrent call GetElements() function and preserve the order defined in elementInput (based on index)

elementInput := []string{FB_FRIENDS, BEAUTY_USERS, FITNESS_USERS, COMEDY_USERS}

wg.Add(len(elementInput))

for _, v := range elementInput {
    //create channel
    channel := make(chan *Element)
    //concurrent call
    go GetElements(ctx, page, channel)
    //Preserve the order

    var elementRes = *<-channel
    if len(elementRes.List) > 0 {
        el = append(el, elementRes)
    }

}

wg.Wait()

Solution

  • Your implementation is not concurrent.

    Reason after every subroutine call you are waiting for result, that is making this serial

    Below is Sample implementation similar to your flow

    Go PlayGround with running code -> Sample Application

    func main() {
        Concurrency()
        time.Sleep(2000)
    }
    
    func response(greeter string, channel chan *string) {
        reply := fmt.Sprintf("hello %s", greeter)
        channel <- &reply
    }
    
    
    func Concurrency() {
        events := []string{"ALICE", "BOB"}
        channels := make([]chan *string, 0)
    
        // start concurrently 
        for _, event := range events {
            channel := make(chan *string)
            go response(event, channel)
            channels = append(channels, channel)
        }
    
        // collect response
        response := make([]string, len(channels))
    
        for i := 0; i < len(channels); i++ {
            response[i] = *<-channels[i]
        }
       // print response 
        log.Printf("channel response %v", response)
    }