TCP accept and Go concurrency model -


looking @ net.tcplistener. 1 expect, given go concurrency paradigm, system functionality implemented channel, got chan *net.conn listen() function, or similar that.

but seems accept() way, , blocks, system accept. except it's crippled, because:

  • there no proper select() can use it, because go prefers channels
  • there no way set blocking options server sockets.

so i'm doing like:

    acceptchannel = make(chan *connection)     go func() {       {        rw, err := listener.accept()        if err != nil { ... handle error ... close(acceptchannel) ... return }        s.acceptchannel <-&connection{tcpconn: rw, .... }       }     }() 

just can use multiple server sockets in select, or multiplex wait on accept() other channels. missing something? i'm new go, might overlooking things - did go not implement own blocking system functions own concurrency paradigm? need separate goroutine every socket (possibly hundreds or thousands) want listen with? correct idiom using, or there better way?

your code fine. go further , replace:

s.acceptchannel <-&connection{tcpconn: rw, .... } 

with:

go handleconnection(&connection{tcpconn: rw, .... }) 

as mentioned in comments, routines not system threads, lightweight threads managed go runtime. when create routine every connection, can use blocking operations, easier implement. go runtime selecting routines you, behaviour you're looking somewhere else, buried language. can't see it, it's everywhere.

now, if need more sophisticated and, per our conversation, implement similar select timeout, you're suggesting: push new connection channel , multiplex timer. seems way go in go.

take note can't close accept channel if one of acceptors fails 1 panic while writing it.

my (fuller) example:

newconns := make(chan net.conn)  // every listener spawn following routine go func(l net.listener) {     {         c, err := l.accept()         if err != nil {             // handle error (and example indicate acceptor down)             newconns <- nil             return         }         newconns <- c     } }(listener)  {     select {     case c := <-newconns:         // new connection or nil if acceptor down, in case should         // (respawn, stop when down or explode)     case <-time.after(time.minute):         // timeout branch, no connection minute     } } 

Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -