Skip to content

Commit 05e583c

Browse files
committed
serve: fix handle not isClosingError err to use event.Error
1 parent 6a871f8 commit 05e583c

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

serve.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// SPDX-License-Identifier: BSD-3-Clause
21
// SPDX-FileCopyrightText: Copyright 2021 The Go Language Server Authors
2+
// SPDX-License-Identifier: BSD-3-Clause
33

44
package jsonrpc2
55

@@ -11,23 +11,27 @@ import (
1111
"net"
1212
"os"
1313
"time"
14+
15+
"go.lsp.dev/pkg/event"
1416
)
1517

1618
// NOTE: This file provides an experimental API for serving multiple remote
1719
// jsonrpc2 clients over the network. For now, it is intentionally similar to
1820
// net/http, but that may change in the future as we figure out the correct
1921
// semantics.
2022

21-
// A StreamServer is used to serve incoming jsonrpc2 clients communicating over
23+
// StreamServer is used to serve incoming jsonrpc2 clients communicating over
2224
// a newly created connection.
2325
type StreamServer interface {
2426
ServeStream(context.Context, Conn) error
2527
}
2628

27-
// The ServerFunc type is an adapter that implements the StreamServer interface
29+
// ServerFunc is an adapter that implements the StreamServer interface
2830
// using an ordinary function.
2931
type ServerFunc func(context.Context, Conn) error
3032

33+
// ServeStream implements StreamServer.
34+
//
3135
// ServeStream calls f(ctx, s).
3236
func (f ServerFunc) ServeStream(ctx context.Context, c Conn) error {
3337
return f(ctx, c)
@@ -43,18 +47,21 @@ func HandlerServer(h Handler) StreamServer {
4347
})
4448
}
4549

46-
// ListenAndServe starts an jsonrpc2 server on the given address. If
47-
// idleTimeout is non-zero, ListenAndServe exits after there are no clients for
50+
// ListenAndServe starts an jsonrpc2 server on the given address.
51+
//
52+
// If idleTimeout is non-zero, ListenAndServe exits after there are no clients for
4853
// this duration, otherwise it exits only on error.
4954
func ListenAndServe(ctx context.Context, network, addr string, server StreamServer, idleTimeout time.Duration) error {
5055
ln, err := net.Listen(network, addr)
5156
if err != nil {
5257
return fmt.Errorf("failed to listen %s:%s: %w", network, addr, err)
5358
}
5459
defer ln.Close()
60+
5561
if network == "unix" {
5662
defer os.Remove(addr)
5763
}
64+
5865
return Serve(ctx, ln, server, idleTimeout)
5966
}
6067

@@ -64,6 +71,7 @@ func ListenAndServe(ctx context.Context, network, addr string, server StreamServ
6471
func Serve(ctx context.Context, ln net.Listener, server StreamServer, idleTimeout time.Duration) error {
6572
ctx, cancel := context.WithCancel(ctx)
6673
defer cancel()
74+
6775
// Max duration: ~290 years; surely that's long enough.
6876
const forever = 1<<63 - 1
6977
if idleTimeout <= 0 {
@@ -85,6 +93,7 @@ func Serve(ctx context.Context, ln net.Listener, server StreamServer, idleTimeou
8593
}
8694
return
8795
}
96+
8897
newConns <- nc
8998
}
9099
}()
@@ -101,36 +110,45 @@ func Serve(ctx context.Context, ln net.Listener, server StreamServer, idleTimeou
101110
closedConns <- server.ServeStream(ctx, conn)
102111
stream.Close()
103112
}()
113+
104114
case err := <-doneListening:
105115
return err
116+
106117
case err := <-closedConns:
107118
if !isClosingError(err) {
108-
return err
119+
event.Error(ctx, "closed a connection", err)
109120
}
121+
110122
activeConns--
111123
if activeConns == 0 {
112124
connTimer.Reset(idleTimeout)
113125
}
126+
114127
case <-connTimer.C:
115128
return ErrIdleTimeout
129+
116130
case <-ctx.Done():
117131
return ctx.Err()
118132
}
119133
}
120134
}
121135

122-
// isClosingError reports if the error occurs normally during the process of
123-
// closing a network connection. It uses imperfect heuristics that err on the
124-
// side of false negatives, and should not be used for anything critical.
136+
// isClosingError reports whether the error occurs normally during the process of
137+
// closing a network connection.
138+
//
139+
// It uses imperfect heuristics that err on the side of false negatives,
140+
// and should not be used for anything critical.
125141
func isClosingError(err error) bool {
126142
if errors.Is(err, io.EOF) {
127143
return true
128144
}
145+
129146
// Per https://github.com/golang/go/issues/4373, this error string should not
130147
// change. This is not ideal, but since the worst that could happen here is
131148
// some superfluous logging, it is acceptable.
132149
if err.Error() == "use of closed network connection" {
133150
return true
134151
}
152+
135153
return false
136154
}

0 commit comments

Comments
 (0)