github.com/goplus/gop@v1.2.6/x/jsonrpc2/jsonrpc2.go (about) 1 /* 2 * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Copyright 2018 The Go Authors. All rights reserved. 18 // Use of this source code is governed by a BSD-style 19 // license that can be found in the LICENSE file. 20 21 // Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec. 22 // https://www.jsonrpc.org/specification 23 // It is intended to be compatible with other implementations at the wire level. 24 package jsonrpc2 25 26 import ( 27 "context" 28 "errors" 29 ) 30 31 type dbgFlags int 32 33 const ( 34 DbgFlagVerbose dbgFlags = 1 << iota 35 DbgFlagCall 36 DbgFlagAll = DbgFlagVerbose | DbgFlagCall 37 ) 38 39 var ( 40 Verbose bool 41 debugCall bool 42 ) 43 44 // SetDebug sets debug flags. 45 func SetDebug(flags dbgFlags) { 46 Verbose = (flags & DbgFlagVerbose) != 0 47 debugCall = (flags & (DbgFlagCall | DbgFlagVerbose)) != 0 48 } 49 50 var ( 51 // ErrIdleTimeout is returned when serving timed out waiting for new connections. 52 ErrIdleTimeout = errors.New("timed out waiting for new connections") 53 54 // ErrNotHandled is returned from a Handler or Preempter to indicate it did 55 // not handle the request. 56 // 57 // If a Handler returns ErrNotHandled, the server replies with 58 // ErrMethodNotFound. 59 ErrNotHandled = errors.New("JSON RPC not handled") 60 61 // ErrAsyncResponse is returned from a handler to indicate it will generate a 62 // response asynchronously. 63 // 64 // ErrAsyncResponse must not be returned for notifications, 65 // which do not receive responses. 66 ErrAsyncResponse = errors.New("JSON RPC asynchronous response") 67 ) 68 69 // Preempter handles messages on a connection before they are queued to the main 70 // handler. 71 // Primarily this is used for cancel handlers or notifications for which out of 72 // order processing is not an issue. 73 type Preempter interface { 74 // Preempt is invoked for each incoming request before it is queued for handling. 75 // 76 // If Preempt returns ErrNotHandled, the request will be queued, 77 // and eventually passed to a Handle call. 78 // 79 // Otherwise, the result and error are processed as if returned by Handle. 80 // 81 // Preempt must not block. (The Context passed to it is for Values only.) 82 Preempt(ctx context.Context, req *Request) (result interface{}, err error) 83 } 84 85 // A PreempterFunc implements the Preempter interface for a standalone Preempt function. 86 type PreempterFunc func(ctx context.Context, req *Request) (interface{}, error) 87 88 func (f PreempterFunc) Preempt(ctx context.Context, req *Request) (interface{}, error) { 89 return f(ctx, req) 90 } 91 92 var _ Preempter = PreempterFunc(nil) 93 94 // Handler handles messages on a connection. 95 type Handler interface { 96 // Handle is invoked sequentially for each incoming request that has not 97 // already been handled by a Preempter. 98 // 99 // If the Request has a nil ID, Handle must return a nil result, 100 // and any error may be logged but will not be reported to the caller. 101 // 102 // If the Request has a non-nil ID, Handle must return either a 103 // non-nil, JSON-marshalable result, or a non-nil error. 104 // 105 // The Context passed to Handle will be canceled if the 106 // connection is broken or the request is canceled or completed. 107 // (If Handle returns ErrAsyncResponse, ctx will remain uncanceled 108 // until either Cancel or Respond is called for the request's ID.) 109 Handle(ctx context.Context, req *Request) (result interface{}, err error) 110 } 111 112 type defaultHandler struct{} 113 114 func (defaultHandler) Preempt(context.Context, *Request) (interface{}, error) { 115 return nil, ErrNotHandled 116 } 117 118 func (defaultHandler) Handle(context.Context, *Request) (interface{}, error) { 119 return nil, ErrNotHandled 120 } 121 122 // A HandlerFunc implements the Handler interface for a standalone Handle function. 123 type HandlerFunc func(ctx context.Context, req *Request) (interface{}, error) 124 125 func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error) { 126 return f(ctx, req) 127 } 128 129 var _ Handler = HandlerFunc(nil) 130 131 func defaultHandleError(err error) { 132 panic("jsonrpc2: " + err.Error()) 133 } 134 135 // async is a small helper for operations with an asynchronous result that you 136 // can wait for. 137 type async struct { 138 ready chan struct{} // closed when done 139 firstErr chan error // 1-buffered; contains either nil or the first non-nil error 140 } 141 142 func newAsync() *async { 143 var a async 144 a.ready = make(chan struct{}) 145 a.firstErr = make(chan error, 1) 146 a.firstErr <- nil 147 return &a 148 } 149 150 func (a *async) done() { 151 close(a.ready) 152 } 153 154 func (a *async) wait() error { 155 <-a.ready 156 err := <-a.firstErr 157 a.firstErr <- err 158 return err 159 } 160 161 func (a *async) setError(err error) { 162 storedErr := <-a.firstErr 163 if storedErr == nil { 164 storedErr = err 165 } 166 a.firstErr <- storedErr 167 }