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  }