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  }