github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/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 // ErrNotHandled is returned from a handler to indicate it did not handle the 19 // message. 20 ErrNotHandled = errors.New("JSON RPC not handled") 21 // ErrAsyncResponse is returned from a handler to indicate it will generate a 22 // response asynchronously. 23 ErrAsyncResponse = errors.New("JSON RPC asynchronous response") 24 ) 25 26 // Preempter handles messages on a connection before they are queued to the main 27 // handler. 28 // Primarily this is used for cancel handlers or notifications for which out of 29 // order processing is not an issue. 30 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) 35 } 36 37 // Handler handles messages on a connection. 38 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) 42 } 43 44 type defaultHandler struct{} 45 46 func (defaultHandler) Preempt(context.Context, *Request) (interface{}, error) { 47 return nil, ErrNotHandled 48 } 49 50 func (defaultHandler) Handle(context.Context, *Request) (interface{}, error) { 51 return nil, ErrNotHandled 52 } 53 54 type HandlerFunc func(ctx context.Context, req *Request) (interface{}, error) 55 56 func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error) { 57 return f(ctx, req) 58 } 59 60 // async is a small helper for operations with an asynchronous result that you 61 // can wait for. 62 type async struct { 63 ready chan struct{} // signals that the operation has completed 64 errBox chan error // guards the operation result 65 } 66 67 func newAsync() *async { 68 var a async 69 a.ready = make(chan struct{}) 70 a.errBox = make(chan error, 1) 71 a.errBox <- nil 72 return &a 73 } 74 75 func (a *async) done() { 76 close(a.ready) 77 } 78 79 func (a *async) isDone() bool { 80 select { 81 case <-a.ready: 82 return true 83 default: 84 return false 85 } 86 } 87 88 func (a *async) wait() error { 89 <-a.ready 90 err := <-a.errBox 91 a.errBox <- err 92 return err 93 } 94 95 func (a *async) setError(err error) { 96 storedErr := <-a.errBox 97 if storedErr == nil { 98 storedErr = err 99 } 100 a.errBox <- storedErr 101 }