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.
 
 

75 lines
2.2 KiB

package client
import (
"context"
"sig-pub/api/pb"
"sig-pub/pkg/data/entity"
"sig-pub/pkg/mapping"
"sig-pub/pkg/utils/kvcache"
"sig-pub/pkg/utils/retry"
"sig-pub/pkg/zlog"
"time"
cache "github.com/fanjindong/go-cache"
"golang.org/x/sync/singleflight"
)
// TradeInstanceAside 交易实例客户端带缓存
// todo nats 更新监听 更新缓存
// grpc trade instance client
type TradeInstanceAside struct {
marketClient pb.MarketServiceClient
cache *kvcache.KVCache[*entity.TradeInstance]
cacheSf singleflight.Group
}
func NewTradeInstanceAside(marketClient pb.MarketServiceClient) *TradeInstanceAside {
return &TradeInstanceAside{
marketClient: marketClient,
cache: kvcache.NewExpireStore[*entity.TradeInstance](
time.Minute,
cache.WithShards(16),
cache.WithClearInterval(5*time.Minute),
),
}
}
// GetTradeInstance 获取交易实例
// 高频访问,使用缓存 + singleflight
func (c *TradeInstanceAside) GetTradeInstance(ctx context.Context, instId string) (inst *entity.TradeInstance, err error) {
r, err, _ := c.cacheSf.Do(instId, func() (r any, err error) {
return c.getTradeInstance0(ctx, instId)
})
if err != nil {
return
}
inst = r.(*entity.TradeInstance)
return
}
func (c *TradeInstanceAside) getTradeInstance0(ctx context.Context, instId string) (inst *entity.TradeInstance, err error) {
inst, ok := c.cache.Get(instId)
if ok {
return
}
// grpc 获取
rsp, err := c.marketClient.GetTradeInstance(ctx, &pb.ReqGetTradeInstance{InstId: instId})
if err != nil {
return
}
inst = mapping.Proto2TradeInstance(rsp.Inst)
c.cache.Set(instId, inst)
return
}
// ListExchangeTradeInstance 获取交易所支持的交易实例
func (c *TradeInstanceAside) ListExchangeTradeInstance(ctx context.Context, exchange pb.ExchangeType) (marketInsts []*pb.MarketTradeInstance, err error) {
return retry.DoWithStepDelay(10, time.Second, func(retryTimes uint32) ([]*pb.MarketTradeInstance, error) {
rsp, err := c.marketClient.ListMarketTradeInstance(ctx, &pb.ReqListMarketTradeInstance{Exchange: exchange})
if err != nil {
zlog.Errorf("list market trade instances error: retry %d times, %v", retryTimes, err)
return nil, err
}
return rsp.ExchangeInsts, nil
})
}