Hello,It is said that event-driven nonblocking model is not the preferred programming model in Go, so I use "one goroutine for one client" model, but is it OK to handle millions of concurrent goroutines in a server process?
And, how can I "select" millions of channel to see which goroutine has data received?
The "select" statement can only select on predictable number of channels, not on a lot of unpredictable channels. And how can I "select" a TCP Connection (which is not a channel) to see if there is any data arrived? Is there any "design patterns" on concurrent programming in Go?
And, how can I "select" millions of channel to see which goroutine has data received? The "select" statement can only select on predictable number of channels, not on a lot of unpredictable channels. And how can I "select" a TCP Connection (which is not a channel) to see if there is any data arrived? Is there any "design patterns" on concurrent programming in Go?
One common pattern is as follows:- One goroutine per connection.- Goroutine uses blocking read on connection.- Goroutine either process data directly or sends the data to some other goroutine using a channel.Here's an (uncompiled and untested) example showing how to read four byte integers from a connection and send them to a central goroutine using a channel.import ("encoding/binary""log""net")func reader(c net.Conn, ch chan<- int32) {for {var i int32if err := binary.Read(c, binary.BigEndian, &i); err != nil {log.Print(err)return}ch <- i}}The central goroutine reads from the single channel passed to each connection goroutines:func central(ch <-chan int32) {for i := range ch {log.Print(i)}}
Hello John and Peter,Thanks for your replies, I'm a bit clear now. But, if I want to "select" two fds, say, two connections, to read from one connection and write to the other one, and the connection is full-duplex (or in other word - I want to implements a message exchanger), how can I do? Should I start another two goroutines to handle the two directions' communication?
Is it a pattern to avoid "select" on file descriptors, but start a goroutine to block on the fd, then passing received data to the server goroutine through a channel instead?
I want to implements a message exchanger), how can I do? Should I start another two goroutines to handle the two directions' communication?
Yes.This example might be helpful: http://gary.beagledreams.com/page/go-websocket-chat.html The example does not call the connection Read and Write methods directly, but it does show the overall flow of exchanging messages.