Using buffered channel for errors in go when listening and serving

Issue

I am going through a tutorial on building web servers using go.

The author, instead of directly using the http.ListenAndServe() method, he creates the http.Server struct.

He then proceeds by:

  • creating a buffered channel for listening for errors

    serverErrors := make(chan errors, 1)
    
  • spawning the http listening goroutine that binds to that channel

    go func(){
        fmt.Println("starting...")
        serverErrors <- api.ListenAndServe()
    }()
    

The reason behind using a buffered channel is according to the instructor

so that the goroutine can exit if we do not collect this error

There is indeed below in a program a select block where the errors coming from this channel are being collected.

Can anyone pls help me understand how the goroutine gets to exit if we don’t collect the error?

What would be the practical difference had we used an unbuffered channel?

Solution

Short answer:

For any channel (buffered or not), channel reads block if nothing is written to the channel.

For non-buffered channels, channel writes will block if no one is listening.

It is a common technique with error-channels (since only one item will ever be written to the channel), to make it a buffered channel of size 1. It ensures the write will happen without blocking – and the writer goroutine can continue on its way and return.

Therefore the service does not relying on the client caller reading from the error channel to perform its cleanup.

Note: to reclaim a channel re GC, it only has to go out of scope – it does not need to be fully drained. Nor does it need to be closed. Once it goes out of scope from the both ends, it will be GC’ed.

Answered By – colm.anseo

Answer Checked By – David Marino (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.