Skip to content

Commit 5d35a75

Browse files
author
Bryan C. Mills
committed
internal/jsonrpc2_v2: clarify documentation
For golang/go#46520 Change-Id: Id9cdb539ae6f16e03d02f3b00b0b5ee06042a42f Reviewed-on: https://go-review.googlesource.com/c/tools/+/388594 Trust: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Reviewed-by: Ian Cottrell <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent abc106c commit 5d35a75

File tree

4 files changed

+55
-30
lines changed

4 files changed

+55
-30
lines changed

internal/jsonrpc2_v2/conn.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import (
2222
// ConnectionOptions itself implements Binder returning itself unmodified, to
2323
// allow for the simple cases where no per connection information is needed.
2424
type Binder interface {
25-
// Bind is invoked when creating a new connection.
25+
// Bind returns the ConnectionOptions to use when establishing the passed-in
26+
// Connection.
2627
// The connection is not ready to use when Bind is called.
2728
Bind(context.Context, *Connection) (ConnectionOptions, error)
2829
}
@@ -234,10 +235,10 @@ func (a *AsyncCall) Await(ctx context.Context, result interface{}) error {
234235
return json.Unmarshal(r.result, result)
235236
}
236237

237-
// Respond deliverers a response to an incoming Call.
238-
// It is an error to not call this exactly once for any message for which a
239-
// handler has previously returned ErrAsyncResponse. It is also an error to
240-
// call this for any other message.
238+
// Respond delivers a response to an incoming Call.
239+
//
240+
// Respond must be called exactly once for any message for which a handler
241+
// returns ErrAsyncResponse. It must not be called for any other message.
241242
func (c *Connection) Respond(id ID, result interface{}, rerr error) error {
242243
pending := <-c.incomingBox
243244
defer func() { c.incomingBox <- pending }()

internal/jsonrpc2_v2/jsonrpc2.go

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ import (
1515
var (
1616
// ErrIdleTimeout is returned when serving timed out waiting for new connections.
1717
ErrIdleTimeout = errors.New("timed out waiting for new connections")
18-
// ErrNotHandled is returned from a handler to indicate it did not handle the
19-
// message.
18+
19+
// ErrNotHandled is returned from a Handler or Preempter to indicate it did
20+
// not handle the request.
21+
//
22+
// If a Handler returns ErrNotHandled, the server replies with
23+
// ErrMethodNotFound.
2024
ErrNotHandled = errors.New("JSON RPC not handled")
25+
2126
// ErrAsyncResponse is returned from a handler to indicate it will generate a
2227
// response asynchronously.
28+
//
29+
// ErrAsyncResponse must not be returned for notifications,
30+
// which do not receive responses.
2331
ErrAsyncResponse = errors.New("JSON RPC asynchronous response")
2432
)
2533

@@ -28,17 +36,33 @@ var (
2836
// Primarily this is used for cancel handlers or notifications for which out of
2937
// order processing is not an issue.
3038
type Preempter interface {
31-
// Preempt is invoked for each incoming request before it is queued.
32-
// If the request is a call, it must return a value or an error for the reply.
33-
// Preempt should not block or start any new messages on the connection.
34-
Preempt(ctx context.Context, req *Request) (interface{}, error)
39+
// Preempt is invoked for each incoming request before it is queued for handling.
40+
//
41+
// If Preempt returns ErrNotHandled, the request will be queued,
42+
// and eventually passed to a Handle call.
43+
//
44+
// Otherwise, the result and error are processed as if returned by Handle.
45+
//
46+
// Preempt must not block. (The Context passed to it is for Values only.)
47+
Preempt(ctx context.Context, req *Request) (result interface{}, err error)
3548
}
3649

3750
// Handler handles messages on a connection.
3851
type Handler interface {
39-
// Handle is invoked for each incoming request.
40-
// If the request is a call, it must return a value or an error for the reply.
41-
Handle(ctx context.Context, req *Request) (interface{}, error)
52+
// Handle is invoked sequentially for each incoming request that has not
53+
// already been handled by a Preempter.
54+
//
55+
// If the Request has a nil ID, Handle must return a nil result,
56+
// and any error may be logged but will not be reported to the caller.
57+
//
58+
// If the Request has a non-nil ID, Handle must return either a
59+
// non-nil, JSON-marshalable result, or a non-nil error.
60+
//
61+
// The Context passed to Handle will be canceled if the
62+
// connection is broken or the request is canceled or completed.
63+
// (If Handle returns ErrAsyncResponse, ctx will remain uncanceled
64+
// until either Cancel or Respond is called for the request's ID.)
65+
Handle(ctx context.Context, req *Request) (result interface{}, err error)
4266
}
4367

4468
type defaultHandler struct{}
@@ -60,15 +84,15 @@ func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, err
6084
// async is a small helper for operations with an asynchronous result that you
6185
// can wait for.
6286
type async struct {
63-
ready chan struct{} // signals that the operation has completed
64-
errBox chan error // guards the operation result
87+
ready chan struct{} // closed when done
88+
firstErr chan error // 1-buffered; contains either nil or the first non-nil error
6589
}
6690

6791
func newAsync() *async {
6892
var a async
6993
a.ready = make(chan struct{})
70-
a.errBox = make(chan error, 1)
71-
a.errBox <- nil
94+
a.firstErr = make(chan error, 1)
95+
a.firstErr <- nil
7296
return &a
7397
}
7498

@@ -87,15 +111,15 @@ func (a *async) isDone() bool {
87111

88112
func (a *async) wait() error {
89113
<-a.ready
90-
err := <-a.errBox
91-
a.errBox <- err
114+
err := <-a.firstErr
115+
a.firstErr <- err
92116
return err
93117
}
94118

95119
func (a *async) setError(err error) {
96-
storedErr := <-a.errBox
120+
storedErr := <-a.firstErr
97121
if storedErr == nil {
98122
storedErr = err
99123
}
100-
a.errBox <- storedErr
124+
a.firstErr <- storedErr
101125
}

internal/jsonrpc2_v2/serve.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ import (
1818

1919
// Listener is implemented by protocols to accept new inbound connections.
2020
type Listener interface {
21-
// Accept an inbound connection to a server.
22-
// It must block until an inbound connection is made, or the listener is
23-
// shut down.
21+
// Accept accepts an inbound connection to a server.
22+
// It blocks until either an inbound connection is made, or the listener is closed.
2423
Accept(context.Context) (io.ReadWriteCloser, error)
2524

26-
// Close is used to ask a listener to stop accepting new connections.
25+
// Close closes the listener.
26+
// Any blocked Accept or Dial operations will unblock and return errors.
2727
Close() error
2828

2929
// Dialer returns a dialer that can be used to connect to this listener
3030
// locally.
31-
// If a listener does not implement this it will return a nil.
31+
// If a listener does not implement this it will return nil.
3232
Dialer() Dialer
3333
}
3434

internal/jsonrpc2_v2/wire.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import (
1212
// see http://www.jsonrpc.org/specification for details
1313

1414
var (
15-
// ErrUnknown should be used for all non coded errors.
16-
ErrUnknown = NewError(-32001, "JSON RPC unknown error")
1715
// ErrParse is used when invalid JSON was received by the server.
1816
ErrParse = NewError(-32700, "JSON RPC parse error")
1917
// ErrInvalidRequest is used when the JSON sent is not a valid Request object.
@@ -28,11 +26,13 @@ var (
2826
ErrInternal = NewError(-32603, "JSON RPC internal error")
2927

3028
// The following errors are not part of the json specification, but
31-
// compliant extensions specific to this implimentation.
29+
// compliant extensions specific to this implementation.
3230

3331
// ErrServerOverloaded is returned when a message was refused due to a
3432
// server being temporarily unable to accept any new messages.
3533
ErrServerOverloaded = NewError(-32000, "JSON RPC overloaded")
34+
// ErrUnknown should be used for all non coded errors.
35+
ErrUnknown = NewError(-32001, "JSON RPC unknown error")
3636
)
3737

3838
const wireVersion = "2.0"

0 commit comments

Comments
 (0)