func (b *balancer) ServeConn(c net.Conn) { output := make(chan *muduorpc.RpcMessage, 10) // size ? defer close(output) // FIXME: cancel outstandings, otherwise memory leak go func() { defer c.Close() for msg := range output { err := muduorpc.Send(c, msg) if err != nil { log.Println(err) break } } log.Println("close", c.RemoteAddr()) }() for { msg, err := muduorpc.Decode(c) if err != nil { log.Println(err) break } if *msg.Type != *muduorpc.MessageType_REQUEST.Enum() { log.Println("Wrong message type.") break } // log.Printf("%v.%v %v req\n", *msg.Service, *msg.Method, *msg.Id) req := request{msg: msg, output: output} b.requests <- req } }
func (b *backendConn) run() { go func() { defer b.conn.Close() for { resp, err := muduorpc.Decode(b.conn) if err != nil { // FIXME: reject outstandings close(b.requests) } b.mu.Lock() r, ok := b.outstanding[resp.GetId()] if ok { delete(b.outstanding, resp.GetId()) } else { panic("What's wrong?") } b.mu.Unlock() resp.Id = &r.origId r.output <- resp } }() var nextId uint64 = 100 for r := range b.requests { resp := response{r.msg.GetId(), r.output} var newId uint64 = nextId nextId++ b.mu.Lock() b.outstanding[newId] = resp b.mu.Unlock() r.msg.Id = &newId err := muduorpc.Send(b.conn, r.msg) muduo.PanicOnError(err) } }