Home > Software design >  What does a select statement with just a case clause (without case expression) and default case do i
What does a select statement with just a case clause (without case expression) and default case do i

Time:04-06

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)
                }
            }
        }
    }
}

CodePudding user response:

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.

  • Related