From 61d4da980b8f97aa9713ae8bc9ad467e8d43c654 Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Wed, 4 Feb 2026 21:38:02 +0100 Subject: [PATCH] echoserver: do not treat client errors as fatal --- internal/command/worker/run.go | 6 ++++- internal/echoserver/echoserver.go | 44 +++++++++++++++++-------------- internal/echoserver/option.go | 11 ++++++++ 3 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 internal/echoserver/option.go diff --git a/internal/command/worker/run.go b/internal/command/worker/run.go index 9b69fb3..1eab660 100644 --- a/internal/command/worker/run.go +++ b/internal/command/worker/run.go @@ -196,7 +196,11 @@ func runWorker(cmd *cobra.Command, args []string) (err error) { // Use TCP echo server to partially emulate VM's TCP/IP stack, // this way we get port-forwarding working when running in // synthetic mode - echoServer, err := echoserver.New() + echoServerOpts := []echoserver.Option{ + echoserver.WithLogger(logger.Sugar().With("component", "echoserver")), + } + + echoServer, err := echoserver.New(echoServerOpts...) if err != nil { return err } diff --git a/internal/echoserver/echoserver.go b/internal/echoserver/echoserver.go index 19331b7..84aa752 100644 --- a/internal/echoserver/echoserver.go +++ b/internal/echoserver/echoserver.go @@ -6,24 +6,37 @@ import ( "io" "net" "strings" - "syscall" + "go.uber.org/zap" "golang.org/x/sync/errgroup" ) type EchoServer struct { listener net.Listener + logger *zap.SugaredLogger } -func New() (*EchoServer, error) { +func New(opts ...Option) (*EchoServer, error) { listener, err := net.Listen("tcp", ":0") if err != nil { return nil, err } - return &EchoServer{ + echoServer := &EchoServer{ listener: listener, - }, nil + } + + // Apply options + for _, opt := range opts { + opt(echoServer) + } + + // Apply defaults + if echoServer.logger == nil { + echoServer.logger = zap.NewNop().Sugar() + } + + return echoServer, nil } func (echoServer *EchoServer) Addr() string { @@ -55,25 +68,16 @@ func (echoServer *EchoServer) Run(ctx context.Context) error { buf := make([]byte, 4096) - for { - n, err := conn.Read(buf) - if err != nil { - if errors.Is(err, io.EOF) { - return nil - } - - return err + _, err := io.CopyBuffer(conn, conn, buf) + if err != nil { + if errors.Is(err, io.EOF) { + return nil } - _, err = conn.Write(buf[:n]) - if err != nil { - if errors.Is(err, syscall.EPIPE) { - return nil - } - - return err - } + echoServer.logger.Warnf("connection failed: %v", err) } + + return nil }) } }) diff --git a/internal/echoserver/option.go b/internal/echoserver/option.go new file mode 100644 index 0000000..943a582 --- /dev/null +++ b/internal/echoserver/option.go @@ -0,0 +1,11 @@ +package echoserver + +import "go.uber.org/zap" + +type Option func(echoServer *EchoServer) + +func WithLogger(logger *zap.SugaredLogger) Option { + return func(echoServer *EchoServer) { + echoServer.logger = logger + } +}