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  }