Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
// 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
}
Пример #4
0
// 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
}