Skip to content

Commit 7b3e9a7

Browse files
committed
handler: add handler interface
1 parent 36390d7 commit 7b3e9a7

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

handler.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright 2020 The go-language-server Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package jsonrpc2
6+
7+
import "context"
8+
9+
// Handler is the interface used to hook into the message handling of an rpc
10+
// connection.
11+
type Handler interface {
12+
// Deliver is invoked to handle incoming requests.
13+
// If the request returns false from IsNotify then the Handler must eventually
14+
// call Reply on the Conn with the supplied request.
15+
// Handlers are called synchronously, they should pass the work off to a go
16+
// routine if they are going to take a long time.
17+
// If Deliver returns true all subsequent handlers will be invoked with
18+
// delivered set to true, and should not attempt to deliver the message.
19+
Deliver(ctx context.Context, r *Request, delivered bool) bool
20+
21+
// Cancel is invoked for canceled outgoing requests.
22+
// It is okay to use the connection to send notifications, but the context will
23+
// be in the canceled state, so you must do it with the background context
24+
// instead.
25+
// If Cancel returns true all subsequent handlers will be invoked with
26+
// canceled set to true, and should not attempt to cancel the message.
27+
Cancel(ctx context.Context, conn *Conn, id ID, canceled bool) bool
28+
29+
// Log is invoked for all messages flowing through a Conn.
30+
// direction indicates if the message being received or sent
31+
// id is the message id, if not set it was a notification
32+
// elapsed is the time between a call being seen and the response, and is
33+
// negative for anything that is not a response.
34+
// method is the method name specified in the message
35+
// payload is the parameters for a call or notification, and the result for a
36+
// response
37+
38+
// Request is called near the start of processing any request.
39+
Request(ctx context.Context, conn *Conn, direction Direction, r *WireRequest) context.Context
40+
41+
// Response is called near the start of processing any response.
42+
Response(ctx context.Context, conn *Conn, direction Direction, r *WireResponse) context.Context
43+
44+
// Done is called when any request is fully processed.
45+
// For calls, this means the response has also been processed, for notifies
46+
// this is as soon as the message has been written to the stream.
47+
// If err is set, it implies the request failed.
48+
Done(ctx context.Context, err error)
49+
50+
// Read is called with a count each time some data is read from the stream.
51+
// The read calls are delayed until after the data has been interpreted so
52+
// that it can be attributed to a request/response.
53+
Read(ctx context.Context, n int64) context.Context
54+
55+
// Write is called each time some data is written to the stream.
56+
Write(ctx context.Context, n int64) context.Context
57+
58+
// Error is called with errors that cannot be delivered through the normal
59+
// mechanisms, for instance a failure to process a notify cannot be delivered
60+
// back to the other party.
61+
Error(ctx context.Context, err error)
62+
}
63+
64+
// Direction is used to indicate to a logger whether the logged message was being
65+
// sent or received.
66+
type Direction bool
67+
68+
const (
69+
// Send indicates the message is outgoing.
70+
Send = Direction(true)
71+
// Receive indicates the message is incoming.
72+
Receive = Direction(false)
73+
)
74+
75+
func (d Direction) String() string {
76+
switch d {
77+
case Send:
78+
return "send"
79+
case Receive:
80+
return "receive"
81+
default:
82+
panic("unreachable")
83+
}
84+
}
85+
86+
// emptyHandler represents a empty handler which implements Handler interface.
87+
type emptyHandler struct{}
88+
89+
// compile time check whether the emptyHandler implements Handler interface.
90+
var _ Handler = (*emptyHandler)(nil)
91+
92+
func (emptyHandler) Deliver(ctx context.Context, r *Request, delivered bool) bool {
93+
if delivered {
94+
return false
95+
}
96+
if !r.IsNotify() {
97+
if err := r.Reply(ctx, nil, Errorf(MethodNotFound, "method %s not found", r.Method)); err != nil {
98+
return false
99+
}
100+
}
101+
return true
102+
}
103+
104+
// Cancel implements Handler interface.
105+
func (emptyHandler) Cancel(context.Context, *Conn, ID, bool) bool { return false }
106+
107+
// Request implements Handler interface.
108+
func (emptyHandler) Request(ctx context.Context, _ *Conn, _ Direction, _ *WireRequest) context.Context {
109+
return ctx
110+
}
111+
112+
// Response implements Handler interface.
113+
func (emptyHandler) Response(ctx context.Context, _ *Conn, _ Direction, _ *WireResponse) context.Context {
114+
return ctx
115+
}
116+
117+
// Done implements Handler interface.
118+
func (emptyHandler) Done(context.Context, error) {}
119+
120+
// Read implements Handler interface.
121+
func (emptyHandler) Read(ctx context.Context, _ int64) context.Context { return ctx }
122+
123+
// Write implements Handler interface.
124+
func (emptyHandler) Write(ctx context.Context, _ int64) context.Context { return ctx }
125+
126+
// Error implements Handler interface.
127+
func (emptyHandler) Error(context.Context, error) {}

0 commit comments

Comments
 (0)