golang.org/x/tools@v0.21.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  
    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  // A PreempterFunc implements the Preempter interface for a standalone Preempt function.
    51  type PreempterFunc func(ctx context.Context, req *Request) (interface{}, error)
    52  
    53  func (f PreempterFunc) Preempt(ctx context.Context, req *Request) (interface{}, error) {
    54  	return f(ctx, req)
    55  }
    56  
    57  var _ Preempter = PreempterFunc(nil)
    58  
    59  // Handler handles messages on a connection.
    60  type Handler interface {
    61  	// Handle is invoked sequentially for each incoming request that has not
    62  	// already been handled by a Preempter.
    63  	//
    64  	// If the Request has a nil ID, Handle must return a nil result,
    65  	// and any error may be logged but will not be reported to the caller.
    66  	//
    67  	// If the Request has a non-nil ID, Handle must return either a
    68  	// non-nil, JSON-marshalable result, or a non-nil error.
    69  	//
    70  	// The Context passed to Handle will be canceled if the
    71  	// connection is broken or the request is canceled or completed.
    72  	// (If Handle returns ErrAsyncResponse, ctx will remain uncanceled
    73  	// until either Cancel or Respond is called for the request's ID.)
    74  	Handle(ctx context.Context, req *Request) (result interface{}, err error)
    75  }
    76  
    77  type defaultHandler struct{}
    78  
    79  func (defaultHandler) Preempt(context.Context, *Request) (interface{}, error) {
    80  	return nil, ErrNotHandled
    81  }
    82  
    83  func (defaultHandler) Handle(context.Context, *Request) (interface{}, error) {
    84  	return nil, ErrNotHandled
    85  }
    86  
    87  // A HandlerFunc implements the Handler interface for a standalone Handle function.
    88  type HandlerFunc func(ctx context.Context, req *Request) (interface{}, error)
    89  
    90  func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error) {
    91  	return f(ctx, req)
    92  }
    93  
    94  var _ Handler = HandlerFunc(nil)
    95  
    96  // async is a small helper for operations with an asynchronous result that you
    97  // can wait for.
    98  type async struct {
    99  	ready    chan struct{} // closed when done
   100  	firstErr chan error    // 1-buffered; contains either nil or the first non-nil error
   101  }
   102  
   103  func newAsync() *async {
   104  	var a async
   105  	a.ready = make(chan struct{})
   106  	a.firstErr = make(chan error, 1)
   107  	a.firstErr <- nil
   108  	return &a
   109  }
   110  
   111  func (a *async) done() {
   112  	close(a.ready)
   113  }
   114  
   115  func (a *async) isDone() bool {
   116  	select {
   117  	case <-a.ready:
   118  		return true
   119  	default:
   120  		return false
   121  	}
   122  }
   123  
   124  func (a *async) wait() error {
   125  	<-a.ready
   126  	err := <-a.firstErr
   127  	a.firstErr <- err
   128  	return err
   129  }
   130  
   131  func (a *async) setError(err error) {
   132  	storedErr := <-a.firstErr
   133  	if storedErr == nil {
   134  		storedErr = err
   135  	}
   136  	a.firstErr <- storedErr
   137  }