// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec. // https://www.jsonrpc.org/specification // It is intended to be compatible with other implementations at the wire level. package jsonrpc2 import ( "context" "errors" ) var ( // ErrIdleTimeout is returned when serving timed out waiting for new connections. ErrIdleTimeout = errors.New("timed out waiting for new connections") // ErrNotHandled is returned from a handler to indicate it did not handle the // message. ErrNotHandled = errors.New("JSON RPC not handled") // ErrAsyncResponse is returned from a handler to indicate it will generate a // response asynchronously. ErrAsyncResponse = errors.New("JSON RPC asynchronous response") ) // Preempter handles messages on a connection before they are queued to the main // handler. // Primarily this is used for cancel handlers or notifications for which out of // order processing is not an issue. type Preempter interface { // Preempt is invoked for each incoming request before it is queued. // If the request is a call, it must return a value or an error for the reply. // Preempt should not block or start any new messages on the connection. Preempt(ctx context.Context, req *Request) (interface{}, error) } // Handler handles messages on a connection. type Handler interface { // Handle is invoked for each incoming request. // If the request is a call, it must return a value or an error for the reply. Handle(ctx context.Context, req *Request) (interface{}, error) } type defaultHandler struct{} func (defaultHandler) Preempt(context.Context, *Request) (interface{}, error) { return nil, ErrNotHandled } func (defaultHandler) Handle(context.Context, *Request) (interface{}, error) { return nil, ErrNotHandled } type HandlerFunc func(ctx context.Context, req *Request) (interface{}, error) func (f HandlerFunc) Handle(ctx context.Context, req *Request) (interface{}, error) { return f(ctx, req) } // async is a small helper for things with an asynchronous result that you can // wait for. type async struct { ready chan struct{} errBox chan error } func (a *async) init() { a.ready = make(chan struct{}) a.errBox = make(chan error, 1) a.errBox <- nil } func (a *async) done() { close(a.ready) } func (a *async) isDone() bool { select { case <-a.ready: return true default: return false } } func (a *async) wait() error { <-a.ready err := <-a.errBox a.errBox <- err return err } func (a *async) setError(err error) { storedErr := <-a.errBox if storedErr == nil { storedErr = err } a.errBox <- storedErr }