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
75 lines
2.2 KiB
package aside |
|
|
|
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 |
|
}) |
|
}
|
|
|