github.com/okex/exchain@v1.8.0/libs/tendermint/abci/client/client.go (about)

     1  package abcicli
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/okex/exchain/libs/tendermint/abci/types"
     7  	"github.com/okex/exchain/libs/tendermint/libs/service"
     8  )
     9  
    10  const (
    11  	dialRetryIntervalSeconds = 3
    12  	echoRetryIntervalSeconds = 1
    13  )
    14  
    15  // Client defines an interface for an ABCI client.
    16  // All `Async` methods return a `ReqRes` object.
    17  // All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error.
    18  // Note these are client errors, eg. ABCI socket connectivity issues.
    19  // Application-related errors are reflected in response via ABCI error codes and logs.
    20  type Client interface {
    21  	service.Service
    22  
    23  	SetResponseCallback(Callback)
    24  	Error() error
    25  
    26  	FlushAsync() *ReqRes
    27  	EchoAsync(msg string) *ReqRes
    28  	InfoAsync(types.RequestInfo) *ReqRes
    29  	SetOptionAsync(types.RequestSetOption) *ReqRes
    30  	DeliverTxAsync(types.RequestDeliverTx) *ReqRes
    31  	PreDeliverRealTxAsync([]byte) types.TxEssentials
    32  	DeliverRealTxAsync(types.TxEssentials) *ReqRes
    33  	CheckTxAsync(types.RequestCheckTx) *ReqRes
    34  	QueryAsync(types.RequestQuery) *ReqRes
    35  	CommitAsync(types.RequestCommit) *ReqRes
    36  	InitChainAsync(types.RequestInitChain) *ReqRes
    37  	BeginBlockAsync(types.RequestBeginBlock) *ReqRes
    38  	EndBlockAsync(types.RequestEndBlock) *ReqRes
    39  
    40  	FlushSync() error
    41  	EchoSync(msg string) (*types.ResponseEcho, error)
    42  	InfoSync(types.RequestInfo) (*types.ResponseInfo, error)
    43  	SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error)
    44  	DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error)
    45  	CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error)
    46  	QuerySync(types.RequestQuery) (*types.ResponseQuery, error)
    47  	CommitSync(types.RequestCommit) (*types.ResponseCommit, error)
    48  	InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error)
    49  	BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error)
    50  	EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error)
    51  	ParallelTxs([][]byte, bool) []*types.ResponseDeliverTx
    52  }
    53  
    54  //----------------------------------------
    55  
    56  //----------------------------------------
    57  
    58  type Callback func(*types.Request, *types.Response)
    59  
    60  //----------------------------------------
    61  
    62  type ReqRes struct {
    63  	*types.Request
    64  	*sync.WaitGroup
    65  	*types.Response // Not set atomically, so be sure to use WaitGroup.
    66  
    67  	mtx  sync.Mutex
    68  	done bool                  // Gets set to true once *after* WaitGroup.Done().
    69  	cb   func(*types.Response) // A single callback that may be set.
    70  }
    71  
    72  func NewReqRes(req *types.Request) *ReqRes {
    73  	return &ReqRes{
    74  		Request:   req,
    75  		WaitGroup: waitGroup1(),
    76  		Response:  nil,
    77  
    78  		done: false,
    79  		cb:   nil,
    80  	}
    81  }
    82  
    83  // Sets the callback for this ReqRes atomically.
    84  // If reqRes is already done, calls cb immediately.
    85  // NOTE: reqRes.cb should not change if reqRes.done.
    86  // NOTE: only one callback is supported.
    87  func (reqRes *ReqRes) SetCallback(cb func(res *types.Response)) {
    88  	reqRes.mtx.Lock()
    89  
    90  	if reqRes.done {
    91  		reqRes.mtx.Unlock()
    92  		cb(reqRes.Response)
    93  		return
    94  	}
    95  
    96  	reqRes.cb = cb
    97  	reqRes.mtx.Unlock()
    98  }
    99  
   100  func (reqRes *ReqRes) GetCallback() func(*types.Response) {
   101  	reqRes.mtx.Lock()
   102  	defer reqRes.mtx.Unlock()
   103  	return reqRes.cb
   104  }
   105  
   106  // NOTE: it should be safe to read reqRes.cb without locks after this.
   107  func (reqRes *ReqRes) SetDone() {
   108  	reqRes.mtx.Lock()
   109  	reqRes.done = true
   110  	reqRes.mtx.Unlock()
   111  }
   112  
   113  func waitGroup1() (wg *sync.WaitGroup) {
   114  	wg = &sync.WaitGroup{}
   115  	wg.Add(1)
   116  	return
   117  }