Allow late connecting
This commit is contained in:
parent
6785b9a3b6
commit
83fc4fc3b6
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
. "github.com/tendermint/go-common"
|
. "github.com/tendermint/go-common"
|
||||||
"github.com/tendermint/tmsp/types"
|
"github.com/tendermint/tmsp/types"
|
||||||
|
@ -27,45 +28,68 @@ type Client struct {
|
||||||
|
|
||||||
reqQueue chan *ReqRes
|
reqQueue chan *ReqRes
|
||||||
flushTimer *ThrottleTimer
|
flushTimer *ThrottleTimer
|
||||||
|
mustConnect bool
|
||||||
|
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
addr string
|
addr string
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
bufWriter *bufio.Writer
|
|
||||||
err error
|
err error
|
||||||
reqSent *list.List
|
reqSent *list.List
|
||||||
resCb func(*types.Request, *types.Response) // listens to all callbacks
|
resCb func(*types.Request, *types.Response) // listens to all callbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(addr string) (*Client, error) {
|
func NewClient(addr string, mustConnect bool) (*Client, error) {
|
||||||
conn, err := Connect(addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cli := &Client{
|
cli := &Client{
|
||||||
reqQueue: make(chan *ReqRes, reqQueueSize),
|
reqQueue: make(chan *ReqRes, reqQueueSize),
|
||||||
flushTimer: NewThrottleTimer("Client", flushThrottleMS),
|
flushTimer: NewThrottleTimer("Client", flushThrottleMS),
|
||||||
|
mustConnect: mustConnect,
|
||||||
|
|
||||||
conn: conn,
|
addr: addr,
|
||||||
bufWriter: bufio.NewWriter(conn),
|
|
||||||
reqSent: list.New(),
|
reqSent: list.New(),
|
||||||
resCb: nil,
|
resCb: nil,
|
||||||
}
|
}
|
||||||
cli.QuitService = *NewQuitService(nil, "Client", cli)
|
cli.QuitService = *NewQuitService(nil, "Client", cli)
|
||||||
cli.Start() // Just start it, it's confusing for callers to remember to start.
|
_, err := cli.Start() // Just start it, it's confusing for callers to remember to start.
|
||||||
|
if mustConnect {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
return cli, nil
|
return cli, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) OnStart() error {
|
func (cli *Client) OnStart() (err error) {
|
||||||
cli.QuitService.OnStart()
|
cli.QuitService.OnStart()
|
||||||
go cli.sendRequestsRoutine()
|
doneCh := make(chan struct{})
|
||||||
go cli.recvResponseRoutine()
|
go func() {
|
||||||
return nil
|
RETRY_LOOP:
|
||||||
|
for {
|
||||||
|
conn, err_ := Connect(cli.addr)
|
||||||
|
if err_ != nil {
|
||||||
|
if cli.mustConnect {
|
||||||
|
err = err_ // OnStart() will return this.
|
||||||
|
close(doneCh)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
fmt.Printf("tmsp.Client failed to connect to %v. Retrying...\n", cli.addr)
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
continue RETRY_LOOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go cli.sendRequestsRoutine(conn)
|
||||||
|
go cli.recvResponseRoutine(conn)
|
||||||
|
close(doneCh) // OnStart() will return no error.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
<-doneCh
|
||||||
|
return // err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) OnStop() {
|
func (cli *Client) OnStop() {
|
||||||
cli.QuitService.OnStop()
|
cli.QuitService.OnStop()
|
||||||
|
if cli.conn != nil {
|
||||||
cli.conn.Close()
|
cli.conn.Close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set listener for all responses
|
// Set listener for all responses
|
||||||
|
@ -78,7 +102,7 @@ func (cli *Client) SetResponseCallback(resCb Callback) {
|
||||||
|
|
||||||
func (cli *Client) StopForError(err error) {
|
func (cli *Client) StopForError(err error) {
|
||||||
cli.mtx.Lock()
|
cli.mtx.Lock()
|
||||||
// log.Error("Stopping Client for error.", "error", err)
|
fmt.Printf("Stopping tmsp.Client for error: %v\n", err.Error())
|
||||||
if cli.err == nil {
|
if cli.err == nil {
|
||||||
cli.err = err
|
cli.err = err
|
||||||
}
|
}
|
||||||
|
@ -94,7 +118,8 @@ func (cli *Client) Error() error {
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
func (cli *Client) sendRequestsRoutine() {
|
func (cli *Client) sendRequestsRoutine(conn net.Conn) {
|
||||||
|
w := bufio.NewWriter(conn)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-cli.flushTimer.Ch:
|
case <-cli.flushTimer.Ch:
|
||||||
|
@ -107,14 +132,14 @@ func (cli *Client) sendRequestsRoutine() {
|
||||||
return
|
return
|
||||||
case reqres := <-cli.reqQueue:
|
case reqres := <-cli.reqQueue:
|
||||||
cli.willSendReq(reqres)
|
cli.willSendReq(reqres)
|
||||||
err := types.WriteMessage(reqres.Request, cli.bufWriter)
|
err := types.WriteMessage(reqres.Request, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.StopForError(err)
|
cli.StopForError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// log.Debug("Sent request", "requestType", reflect.TypeOf(reqres.Request), "request", reqres.Request)
|
// log.Debug("Sent request", "requestType", reflect.TypeOf(reqres.Request), "request", reqres.Request)
|
||||||
if reqres.Request.Type == types.MessageType_Flush {
|
if reqres.Request.Type == types.MessageType_Flush {
|
||||||
err = cli.bufWriter.Flush()
|
err = w.Flush()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.StopForError(err)
|
cli.StopForError(err)
|
||||||
return
|
return
|
||||||
|
@ -124,8 +149,8 @@ func (cli *Client) sendRequestsRoutine() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) recvResponseRoutine() {
|
func (cli *Client) recvResponseRoutine(conn net.Conn) {
|
||||||
r := bufio.NewReader(cli.conn) // Buffer reads
|
r := bufio.NewReader(conn) // Buffer reads
|
||||||
for {
|
for {
|
||||||
var res = &types.Response{}
|
var res = &types.Response{}
|
||||||
err := types.ReadMessage(r, res)
|
err := types.ReadMessage(r, res)
|
||||||
|
|
|
@ -70,7 +70,7 @@ func startApp() *process.Process {
|
||||||
|
|
||||||
func startClient() *tmspcli.Client {
|
func startClient() *tmspcli.Client {
|
||||||
// Start client
|
// Start client
|
||||||
client, err := tmspcli.NewClient("tcp://127.0.0.1:46658")
|
client, err := tmspcli.NewClient("tcp://127.0.0.1:46658", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("connecting to counter_app: " + err.Error())
|
panic("connecting to counter_app: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue