func (mc *muxConn) Read(data []byte) (n int, err error) { defer func() { if vnet.SocketClosed(err) { err = io.EOF } }() n, err = mc.readPipe.Read(data) return }
func (mc *muxConn) Write(data []byte) (n int, err error) { defer func() { if vnet.SocketClosed(err) { err = io.EOF } }() for len(data) > 0 { // make one attempt to write at most defaultBufSize bytes to the // underlying connection func() { // claim channel (acts as a mutex) conn := <-mc.connCh defer func() { mc.connCh <- conn }() // short circuit if we've seen an error on this connection. if *mc.writeErr != nil { data = nil // stop loop err = *mc.writeErr return } // update based on any errors seen on this write attempt defer func() { *mc.writeErr = err }() enc := gob.NewEncoder(conn) // write at most a fixed amount (additional data will have to wait // for the next loop iteration) to_write := defaultBufSize if len(data) < to_write { to_write = len(data) } if err = enc.Encode(mc.chno); err != nil { return } if err = enc.Encode(to_write); err != nil { return } if err = enc.Encode(data[:to_write]); err != nil { return } n += to_write data = data[to_write:] }() } return }
// ServeListenerForever is the same as ServeForever except it uses the specified // listener. This is useful in testing when an ephemeral port should be used. func ServeListenerForever(l net.Listener) error { // Wrap with logger handler := logginghandler.New(http.DefaultServeMux, log.GetVerbosity()) _, aps, err := net.SplitHostPort(l.Addr().String()) if err != nil { log.Errorf("govtil/net/server: failed to get port - %v", err) } log.Printf("govtil/net/server: starting on port %v", aps) // Serve err = http.Serve(l, handler) if err != nil { if vnet.SocketClosed(err) { err = nil // closed due to signal, no error } else { log.Errorf("govtil/net/server: %v", err) } } log.Println("govtil/net/server: Terminating") return err }
// Serve on a given port // // The server will log to the default logger and will gracefully terminate on // receipt of an interrupt or kill signal. // // The following URLs are defined: // / // /healthz // /varz // /streamz // /birpc // /debug/pprof // func ServeForever(port int) error { addr := ":" + fmt.Sprint(port) l, err := net.Listen("tcp", addr) if err != nil { log.Errorln("govtil/net/server: Failed to listen on", port, err) return err } // Close listen port on signals (causes http.Serve() to return) sigch := make(chan os.Signal) signal.Notify(sigch, []os.Signal{ syscall.SIGABRT, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGPWR, syscall.SIGQUIT, syscall.SIGSTOP, syscall.SIGTERM, }...) go func() { sig := <-sigch log.Println("govtil/net/server: Closing listen port", l.Addr().String(), "due to signal", sig) l.Close() }() logginghandler := logginghandler.New(http.DefaultServeMux, log.NORMAL) err = http.Serve(l, logginghandler) if err != nil { if vnet.SocketClosed(err) { err = nil // closed due to signal, no error } else { log.Errorln("govtil/net/server:", err) } } log.Println("govtil/net/server: Terminating") return err }