How to reply to the sender of a channel and manage state

Issue

I would like to know how to reply directly to the sender of a channel in Go. More interesting is how to identify the sender for later use.

I am comparing this to Elixir GenServer where I can reply to the sender directly or broadcast to everyone. Is this feature missing in Go?

Everywhere I read about channels in Go I cannot find how to do this.

Also, GenServers in Elixir hold states becomes it is a infinite running process. Does Go have semething similar to hold and pass state? If not how is this accomplished?

Solution

Communicating with a channel sender

As already mentioned, a channel of channels is a way to respond directly to the channel sender. Here is an example:

package main

func main() {
    // Make a communication channel by creating a channel of channels
    c := make(chan chan struct{})
    // Start a sender with the communication channel
    go sender(c)
    // Receive a message from the sender, in this case the message is a channel itself
    r := <- c
    // Send response to the sender on the channel given to us by the sender
    r <- struct{}{}
}

func sender(c chan chan struct{}) {
    // Create a channel the receiver will use to respond to us
    r := make(chan struct{})
    // Send the channel to the receiver
    c <- r
    // This is the response received after the received got the message
    <- r
}

As to your second question about identifying a specific sender, you may be able to use something like goroutinemap which allows you to manage the lifecycle of named go-routines. This pattern isn’t common however, and if you need to identify a specific channel sender, it’s possible you could (and should) re-design your solution.

Managing application state

This depends entirely on your application and what it does. Edit: according to OP, the application is a chess game over websockets. You could consider creating a data structure with references to both player’s websocket connections, as well as the game state between the players. This data structure would get created when a game is started, then the data structure could manage the messages back and forth between the players and the updating of the game state internally. Perhaps something like

type GameState struct {
    Player1 *websocket.Conn
    Player2 *websocket.Conn
    // Add any game state needed here
}

func (s *GameState) run(ctx context.Context) {
    // Send messages between websocket connections here and update game state accordingly
}

Answered By – Clark McCauley

Answer Checked By – Senaida (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.