You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.3 KiB

  1. package tmspcli
  2. import (
  3. "github.com/tendermint/tmsp/types"
  4. "sync"
  5. )
  6. type Client interface {
  7. SetResponseCallback(Callback)
  8. Error() error
  9. Stop() bool
  10. FlushAsync() *ReqRes
  11. EchoAsync(msg string) *ReqRes
  12. InfoAsync() *ReqRes
  13. SetOptionAsync(key string, value string) *ReqRes
  14. AppendTxAsync(tx []byte) *ReqRes
  15. CheckTxAsync(tx []byte) *ReqRes
  16. QueryAsync(tx []byte) *ReqRes
  17. CommitAsync() *ReqRes
  18. FlushSync() error
  19. EchoSync(msg string) (res types.Result)
  20. InfoSync() (res types.Result)
  21. SetOptionSync(key string, value string) (res types.Result)
  22. AppendTxSync(tx []byte) (res types.Result)
  23. CheckTxSync(tx []byte) (res types.Result)
  24. QuerySync(tx []byte) (res types.Result)
  25. CommitSync() (res types.Result)
  26. InitChainAsync(validators []*types.Validator) *ReqRes
  27. BeginBlockAsync(height uint64) *ReqRes
  28. EndBlockAsync(height uint64) *ReqRes
  29. InitChainSync(validators []*types.Validator) (err error)
  30. BeginBlockSync(height uint64) (err error)
  31. EndBlockSync(height uint64) (changedValidators []*types.Validator, err error)
  32. }
  33. //----------------------------------------
  34. type Callback func(*types.Request, *types.Response)
  35. //----------------------------------------
  36. type ReqRes struct {
  37. *types.Request
  38. *sync.WaitGroup
  39. *types.Response // Not set atomically, so be sure to use WaitGroup.
  40. mtx sync.Mutex
  41. done bool // Gets set to true once *after* WaitGroup.Done().
  42. cb func(*types.Response) // A single callback that may be set.
  43. }
  44. func NewReqRes(req *types.Request) *ReqRes {
  45. return &ReqRes{
  46. Request: req,
  47. WaitGroup: waitGroup1(),
  48. Response: nil,
  49. done: false,
  50. cb: nil,
  51. }
  52. }
  53. // Sets the callback for this ReqRes atomically.
  54. // If reqRes is already done, calls cb immediately.
  55. // NOTE: reqRes.cb should not change if reqRes.done.
  56. // NOTE: only one callback is supported.
  57. func (reqRes *ReqRes) SetCallback(cb func(res *types.Response)) {
  58. reqRes.mtx.Lock()
  59. if reqRes.done {
  60. reqRes.mtx.Unlock()
  61. cb(reqRes.Response)
  62. return
  63. }
  64. defer reqRes.mtx.Unlock()
  65. reqRes.cb = cb
  66. }
  67. func (reqRes *ReqRes) GetCallback() func(*types.Response) {
  68. reqRes.mtx.Lock()
  69. defer reqRes.mtx.Unlock()
  70. return reqRes.cb
  71. }
  72. // NOTE: it should be safe to read reqRes.cb without locks after this.
  73. func (reqRes *ReqRes) SetDone() {
  74. reqRes.mtx.Lock()
  75. reqRes.done = true
  76. reqRes.mtx.Unlock()
  77. }
  78. func waitGroup1() (wg *sync.WaitGroup) {
  79. wg = &sync.WaitGroup{}
  80. wg.Add(1)
  81. return
  82. }