GoPLS Viewer

Home|gopls/internal/jsonrpc2_v2/jsonrpc2.go
1// Copyright 2018 The Go 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 is a minimal implementation of the JSON RPC 2 spec.
6// https://www.jsonrpc.org/specification
7// It is intended to be compatible with other implementations at the wire level.
8package jsonrpc2
9
10import (
11    "context"
12    "errors"
13)
14
15var (
16    // ErrIdleTimeout is returned when serving timed out waiting for new connections.
17    ErrIdleTimeout = errors.New("timed out waiting for new connections")
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.
24    ErrNotHandled = errors.New("JSON RPC not handled")
25
26    // ErrAsyncResponse is returned from a handler to indicate it will generate a
27    // response asynchronously.
28    //
29    // ErrAsyncResponse must not be returned for notifications,
30    // which do not receive responses.
31    ErrAsyncResponse = errors.New("JSON RPC asynchronous response")
32)
33
34// Preempter handles messages on a connection before they are queued to the main
35// handler.
36// Primarily this is used for cancel handlers or notifications for which out of
37// order processing is not an issue.
38type Preempter interface {
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.Contextreq *Request) (result interface{}, err error)
48}
49
50// A PreempterFunc implements the Preempter interface for a standalone Preempt function.
51type PreempterFunc func(ctx context.Contextreq *Request) (interface{}, error)
52
53func (f PreempterFuncPreempt(ctx context.Contextreq *Request) (interface{}, error) {
54    return f(ctxreq)
55}
56
57var _ Preempter = PreempterFunc(nil)
58
59// Handler handles messages on a connection.
60type Handler interface {
61    // Handle is invoked sequentially for each incoming request that has not
62    // already been handled by a Preempter.
63    //
64    // If the Request has a nil ID, Handle must return a nil result,
65    // and any error may be logged but will not be reported to the caller.
66    //
67    // If the Request has a non-nil ID, Handle must return either a
68    // non-nil, JSON-marshalable result, or a non-nil error.
69    //
70    // The Context passed to Handle will be canceled if the
71    // connection is broken or the request is canceled or completed.
72    // (If Handle returns ErrAsyncResponse, ctx will remain uncanceled
73    // until either Cancel or Respond is called for the request's ID.)
74    Handle(ctx context.Contextreq *Request) (result interface{}, err error)
75}
76
77type defaultHandler struct{}
78
79func (defaultHandlerPreempt(context.Context, *Request) (interface{}, error) {
80    return nilErrNotHandled
81}
82
83func (defaultHandlerHandle(context.Context, *Request) (interface{}, error) {
84    return nilErrNotHandled
85}
86
87// A HandlerFunc implements the Handler interface for a standalone Handle function.
88type HandlerFunc func(ctx context.Contextreq *Request) (interface{}, error)
89
90func (f HandlerFuncHandle(ctx context.Contextreq *Request) (interface{}, error) {
91    return f(ctxreq)
92}
93
94var _ Handler = HandlerFunc(nil)
95
96// async is a small helper for operations with an asynchronous result that you
97// can wait for.
98type async struct {
99    ready    chan struct{} // closed when done
100    firstErr chan error    // 1-buffered; contains either nil or the first non-nil error
101}
102
103func newAsync() *async {
104    var a async
105    a.ready = make(chan struct{})
106    a.firstErr = make(chan error1)
107    a.firstErr <- nil
108    return &a
109}
110
111func (a *asyncdone() {
112    close(a.ready)
113}
114
115func (a *asyncisDone() bool {
116    select {
117    case <-a.ready:
118        return true
119    default:
120        return false
121    }
122}
123
124func (a *asyncwait() error {
125    <-a.ready
126    err := <-a.firstErr
127    a.firstErr <- err
128    return err
129}
130
131func (a *asyncsetError(err error) {
132    storedErr := <-a.firstErr
133    if storedErr == nil {
134        storedErr = err
135    }
136    a.firstErr <- storedErr
137}
138
MembersX
HandlerFunc.Handle.f
defaultHandler.Preempt
HandlerFunc.Handle
async.firstErr
PreempterFunc.Preempt.req
newAsync
async.isDone
defaultHandler.Handle
HandlerFunc
newAsync.a
async.isDone.a
PreempterFunc.Preempt
async.wait
async.setError.a
HandlerFunc.Handle.req
PreempterFunc
PreempterFunc.Preempt.f
defaultHandler
async
async.ready
async.setError
Preempter
Handler
HandlerFunc.Handle.ctx
async.done.a
async.done
async.wait.a
async.setError.err
PreempterFunc.Preempt.ctx
Members
X