functional/agent/handler.go
func (srv *Server) runEtcd() error {
	errc := make(chan error)
	go func() {
		time.Sleep(5 * time.Second)
		// server advertise client/peer listener had to start first
		// before setting up proxy listener
		errc <- srv.startProxy()
	}()

	if srv.etcdCmd != nil {
		srv.lg.Info(
			"starting etcd command",
			zap.String("command-path", srv.etcdCmd.Path),
		)
		err := srv.etcdCmd.Start()
		perr := <-errc
		srv.lg.Info(
			"started etcd command",
			zap.String("command-path", srv.etcdCmd.Path),
			zap.Errors("errors", []error{err, perr}),
		)
		if err != nil {
			return err
		}
		return perr
	}

	select {
	case <-srv.etcdServer.Server.ReadyNotify():
		srv.lg.Info("embedded etcd is ready")
	case <-time.After(time.Minute):
		srv.etcdServer.Close()
		return fmt.Errorf("took too long to start %v", <-srv.etcdServer.Err())
	}
	return <-errc
}
func (srv *Server) runEtcd() error {
	errc := make(chan error)
	go func() {
		time.Sleep(5 * time.Second)
		// server advertise client/peer listener had to start first
		// before setting up proxy listener
		errc <- srv.startProxy()
	}()

	if srv.etcdCmd != nil {
		srv.lg.Info(
			"starting etcd command",
			zap.String("command-path", srv.etcdCmd.Path),
		)
		err := srv.etcdCmd.Start()
		perr := <-errc
		srv.lg.Info(
			"started etcd command",
			zap.String("command-path", srv.etcdCmd.Path),
			zap.Errors("errors", []error{err, perr}),
		)
		if err != nil {
			return err
		}
		return perr
	}

	select {
	case <-srv.etcdServer.Server.ReadyNotify():
		srv.lg.Info("embedded etcd is ready")
	case <-time.After(time.Minute):
		srv.etcdServer.Close()
		return fmt.Errorf("took too long to start %v", <-srv.etcdServer.Err())
	}
	return <-errc
}
// start but do not wait for it to complete