maxapi: improve nonce update with retry

This commit is contained in:
c9s 2023-04-11 18:21:40 +08:00
parent 65a2d21632
commit 8d240e9b4c
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 38 additions and 10 deletions

View File

@ -23,6 +23,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/c9s/bbgo/pkg/util"
"github.com/c9s/bbgo/pkg/util/backoff"
"github.com/c9s/bbgo/pkg/version"
)
@ -147,16 +148,41 @@ func (c *RestClient) Auth(key string, secret string) *RestClient {
return c
}
func (c *RestClient) initNonce() {
var clientTime = time.Now()
var err error
serverTimestamp, err = c.PublicService.Timestamp()
if err != nil {
logger.WithError(err).Panic("failed to sync timestamp with max")
}
func (c *RestClient) queryAndUpdateServerTimestamp(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
timeOffset = serverTimestamp - clientTime.Unix()
logger.Infof("loaded max server timestamp: %d offset=%d", serverTimestamp, timeOffset)
default:
op := func() error {
serverTs, err := c.PublicService.Timestamp()
if err != nil {
return err
}
if serverTs == 0 {
return errors.New("unexpected zero server timestamp")
}
clientTime := time.Now()
offset := serverTs - clientTime.Unix()
atomic.StoreInt64(&serverTimestamp, serverTs)
atomic.StoreInt64(&timeOffset, offset)
logger.Infof("loaded max server timestamp: %d offset=%d", serverTimestamp, offset)
return nil
}
if err := backoff.RetryGeneral(ctx, op); err != nil {
logger.WithError(err).Error("unable to sync timestamp with max")
}
}
}
}
func (c *RestClient) initNonce() {
go c.queryAndUpdateServerTimestamp(context.Background())
}
func (c *RestClient) getNonce() int64 {
@ -164,7 +190,8 @@ func (c *RestClient) getNonce() int64 {
// nonce 與伺服器的時間差不得超過正負30秒每個 nonce 只能使用一次。
var seconds = time.Now().Unix()
var rc = atomic.AddInt64(&reqCount, 1)
return (seconds+timeOffset)*1000 - 1 + int64(math.Mod(float64(rc), 1000.0))
var offset = atomic.LoadInt64(&timeOffset)
return (seconds+offset)*1000 - 1 + int64(math.Mod(float64(rc), 1000.0))
}
func (c *RestClient) NewAuthenticatedRequest(ctx context.Context, m string, refURL string, params url.Values, payload interface{}) (*http.Request, error) {

View File

@ -8,6 +8,7 @@ import (
var MaxRetries uint64 = 101
// RetryGeneral retries operation with max retry times 101 and with the exponential backoff
func RetryGeneral(ctx context.Context, op backoff.Operation) (err error) {
err = backoff.Retry(op, backoff.WithContext(
backoff.WithMaxRetries(