Getting deadlock when using channel as medium to communicate between producer and consumer

Issue

I have created a eventProducer and eventConsumer and a subscribe method on which consumer can subscribe on producer channel. But consumer is not able to access the data of producer channel.

package main

import (
    "fmt"
    "time"
)

type EventProducer struct {
    events chan []string
}

func (e *EventProducer) SubscribeForEvents(ev chan []string) {
    e.events = ev
}

type EventConsumer struct {
    Ep     *EventProducer
    evData chan []string
}

func main() {
    ep := &EventProducer{
        events: make(chan []string, 1),
    }
    
    go func ()  {   
        var data []string
        data = append(data, "ram")
        data = append(data, "errr")
        data = append(data, "rttt")
        fmt.Println(data)
        ep.events <- data
    }()

    time.Sleep(2*time.Second)
    fmt.Println(<-ep.events)
    ec := &EventConsumer{
        Ep:     ep,
        evData: make(chan []string, 1),
    }
    ec.Ep.SubscribeForEvents(ec.evData)
    for cs := range ec.evData {
        fmt.Println(cs)
    }   
}

Solution

there are main two things you need to do

  1. close the channel

Channels aren’t like files; you don’t usually need to close them.
Closing is only necessary when the receiver must be told there are no
more values coming, such as to terminate a range loop.

  1. there is no need for time.Sleep(2*time.Second) Check output on Go Playground

package main

import (
    "fmt"
)

type EventProducer struct {
    events chan []string
}

func (e *EventProducer) SubscribeForEvents(ev chan []string) {
    e.events = ev
}

type EventConsumer struct {
    Ep     *EventProducer
    evData chan []string
}

func main() {
    ep := &EventProducer{
        events: make(chan []string, 1),
    }

    ec := &EventConsumer{
        Ep:     ep,
        evData: make(chan []string, 1),
    }

    go func() {
        var data []string
        data = append(data, "ram")
        data = append(data, "errr")
        data = append(data, "rttt")
        ep.events <- data
        close(ep.events)

    }()

    ec.Ep.SubscribeForEvents(ec.evData)
    for cs := range ec.evData {
        fmt.Println("consumer", cs)
    }

}

Answered By – Manjeet Thakur

Answer Checked By – Cary Denson (GoLangFix Admin)

Leave a Reply

Your email address will not be published.