github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/jsonrpc2_v2/jsonrpc2.go (about) 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. 8 package jsonrpc2 9 10 import ( 11 "context" 12 "errors" 13 ) 14 15 var ( 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. 38 type 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.Context, req *Request) (result interface{}, err error) 48 } 49 50 // Handler handles messages on a connection. 51 type Handler interface { 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) 66 } 67 68 type defaultHandler struct{} 69 70 func (defaultHandler) Preempt(context.Context, *Request) (interface{}, error) { 71 return nil, ErrNotHandled 72 } 73 74 func (defaultHandler) Handle(context.Context, *Request) (interface{}, error) { 75 return nil, ErrNotHandled 76 } 77 78 type HandlerFunc func(ctx context.Context, req *Request) (interface{}, error) 79 80 func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error) { 81 return f(ctx, req) 82 } 83 84 // async is a small helper for operations with an asynchronous result that you 85 // can wait for. 86 type async struct { 87 ready chan struct{} // closed when done 88 firstErr chan error // 1-buffered; contains either nil or the first non-nil error 89 } 90 91 func newAsync() *async { 92 var a async 93 a.ready = make(chan struct{}) 94 a.firstErr = make(chan error, 1) 95 a.firstErr <- nil 96 return &a 97 } 98 99 func (a *async) done() { 100 close(a.ready) 101 } 102 103 func (a *async) isDone() bool { 104 select { 105 case <-a.ready: 106 return true 107 default: 108 return false 109 } 110 } 111 112 func (a *async) wait() error { 113 <-a.ready 114 err := <-a.firstErr 115 a.firstErr <- err 116 return err 117 } 118 119 func (a *async) setError(err error) { 120 storedErr := <-a.firstErr 121 if storedErr == nil { 122 storedErr = err 123 } 124 a.firstErr <- storedErr 125 }