github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/abci/client/client.go (about) 1 package abcicli 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/franono/tendermint/abci/types" 8 "github.com/franono/tendermint/libs/service" 9 ) 10 11 const ( 12 dialRetryIntervalSeconds = 3 13 echoRetryIntervalSeconds = 1 14 ) 15 16 // Client defines an interface for an ABCI client. 17 // All `Async` methods return a `ReqRes` object. 18 // All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error. 19 // Note these are client errors, eg. ABCI socket connectivity issues. 20 // Application-related errors are reflected in response via ABCI error codes and logs. 21 type Client interface { 22 service.Service 23 24 SetResponseCallback(Callback) 25 Error() error 26 27 FlushAsync() *ReqRes 28 EchoAsync(msg string) *ReqRes 29 InfoAsync(types.RequestInfo) *ReqRes 30 SetOptionAsync(types.RequestSetOption) *ReqRes 31 DeliverTxAsync(types.RequestDeliverTx) *ReqRes 32 CheckTxAsync(types.RequestCheckTx) *ReqRes 33 QueryAsync(types.RequestQuery) *ReqRes 34 CommitAsync() *ReqRes 35 InitChainAsync(types.RequestInitChain) *ReqRes 36 BeginBlockAsync(types.RequestBeginBlock) *ReqRes 37 EndBlockAsync(types.RequestEndBlock) *ReqRes 38 ListSnapshotsAsync(types.RequestListSnapshots) *ReqRes 39 OfferSnapshotAsync(types.RequestOfferSnapshot) *ReqRes 40 LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk) *ReqRes 41 ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk) *ReqRes 42 43 FlushSync() error 44 EchoSync(msg string) (*types.ResponseEcho, error) 45 InfoSync(types.RequestInfo) (*types.ResponseInfo, error) 46 SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error) 47 DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error) 48 CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) 49 QuerySync(types.RequestQuery) (*types.ResponseQuery, error) 50 CommitSync() (*types.ResponseCommit, error) 51 InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) 52 BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) 53 EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) 54 ListSnapshotsSync(types.RequestListSnapshots) (*types.ResponseListSnapshots, error) 55 OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) 56 LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) 57 ApplySnapshotChunkSync(types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) 58 } 59 60 //---------------------------------------- 61 62 // NewClient returns a new ABCI client of the specified transport type. 63 // It returns an error if the transport is not "socket" or "grpc" 64 func NewClient(addr, transport string, mustConnect bool) (client Client, err error) { 65 switch transport { 66 case "socket": 67 client = NewSocketClient(addr, mustConnect) 68 case "grpc": 69 client = NewGRPCClient(addr, mustConnect) 70 default: 71 err = fmt.Errorf("unknown abci transport %s", transport) 72 } 73 return 74 } 75 76 //---------------------------------------- 77 78 type Callback func(*types.Request, *types.Response) 79 80 //---------------------------------------- 81 82 type ReqRes struct { 83 *types.Request 84 *sync.WaitGroup 85 *types.Response // Not set atomically, so be sure to use WaitGroup. 86 87 mtx sync.Mutex 88 done bool // Gets set to true once *after* WaitGroup.Done(). 89 cb func(*types.Response) // A single callback that may be set. 90 } 91 92 func NewReqRes(req *types.Request) *ReqRes { 93 return &ReqRes{ 94 Request: req, 95 WaitGroup: waitGroup1(), 96 Response: nil, 97 98 done: false, 99 cb: nil, 100 } 101 } 102 103 // Sets the callback for this ReqRes atomically. 104 // If reqRes is already done, calls cb immediately. 105 // NOTE: reqRes.cb should not change if reqRes.done. 106 // NOTE: only one callback is supported. 107 func (reqRes *ReqRes) SetCallback(cb func(res *types.Response)) { 108 reqRes.mtx.Lock() 109 110 if reqRes.done { 111 reqRes.mtx.Unlock() 112 cb(reqRes.Response) 113 return 114 } 115 116 reqRes.cb = cb 117 reqRes.mtx.Unlock() 118 } 119 120 func (reqRes *ReqRes) GetCallback() func(*types.Response) { 121 reqRes.mtx.Lock() 122 defer reqRes.mtx.Unlock() 123 return reqRes.cb 124 } 125 126 // NOTE: it should be safe to read reqRes.cb without locks after this. 127 func (reqRes *ReqRes) SetDone() { 128 reqRes.mtx.Lock() 129 reqRes.done = true 130 reqRes.mtx.Unlock() 131 } 132 133 func waitGroup1() (wg *sync.WaitGroup) { 134 wg = &sync.WaitGroup{} 135 wg.Add(1) 136 return 137 }