github.com/v2fly/tools@v0.100.0/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 // async is a small helper for things with an asynchronous result that you can 55 // wait for. 56 type async struct { 57 ready chan struct{} 58 errBox chan error 59 } 60 61 func (a *async) init() { 62 a.ready = make(chan struct{}) 63 a.errBox = make(chan error, 1) 64 a.errBox <- nil 65 } 66 67 func (a *async) done() { 68 close(a.ready) 69 } 70 71 func (a *async) isDone() bool { 72 select { 73 case <-a.ready: 74 return true 75 default: 76 return false 77 } 78 } 79 80 func (a *async) wait() error { 81 <-a.ready 82 err := <-a.errBox 83 a.errBox <- err 84 return err 85 } 86 87 func (a *async) setError(err error) { 88 storedErr := <-a.errBox 89 if storedErr == nil { 90 storedErr = err 91 } 92 a.errBox <- storedErr 93 }