Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What does a select statement with just a case clause (without case expression) and default case do in Golang?

I have trouble understanding the following excerpt of code. The run() f-n is executed as a goroutine and I think is responsible for dispatching all entries in the ‘gloabl’ broadcast channel to the corresponding client channels (chan.send). I lose track in the second select statement, in the case clause. Does it only push the message struct in the client.send channel or is there more to this specific syntax?

func (h *Hub) run() {
    for {
        select {
        ...
        case message := <-h.broadcast:
            for client := range h.clients[someid] { //clients = make(map[int][]*Client)
                select {
                    case client.send <- message: //???
                    default:
                        close(client.send)
                        delete(h.clients, client)
                }
            }
        }
    }
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

It’s called non-blocking send. Spec: Select statements:

If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed.

If none of the communication ops of the select statement are ready, and there is a default case, it is chosen immediately without waiting for the comm. ops to become ready some time in the future.

The code in question tries to send a message on the client’s channel, and if it’s not ready, the client is dropped immediately. If the send can proceed (because there’s room in the channel’s buffer or there’s a goroutine ready to receive from the channel), the send operation is carried out, and the loop goes on to the next iteration (advances to the next client).

The intention is likely to prevent slow or dead clients to slow down or even block the entire hub. Using an unconditional send operation like client.send <- message, if the client is not ready to receive and process the message, this would block, essentially blocking all other clients and the hub itself.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading