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.
82 lines
2.1 KiB
82 lines
2.1 KiB
package aside |
|
|
|
import ( |
|
"context" |
|
"sig-pub/api/pb" |
|
"sig-pub/pkg/data/entity" |
|
"sig-pub/pkg/mapping" |
|
"sig-pub/pkg/types" |
|
"sig-pub/pkg/utils/kvcache" |
|
"time" |
|
|
|
cache "github.com/fanjindong/go-cache" |
|
"golang.org/x/sync/singleflight" |
|
) |
|
|
|
// TradeInstanceAside 交易实例客户端带缓存 |
|
// todo nats 更新监听 更新缓存 |
|
// grpc trade instance client |
|
type TradeInstanceAside struct { |
|
client pb.MarketClient |
|
cache *kvcache.KVCache[*entity.TradeInstance] |
|
cacheSf singleflight.Group |
|
} |
|
|
|
func NewTradeInstanceAside(client pb.MarketClient) *TradeInstanceAside { |
|
return &TradeInstanceAside{ |
|
client: client, |
|
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.client.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 types.Exchange) (exInsts []*entity.TradeInstanceExchange, err error) { |
|
pbExType, err := exchange.Exchange2PB() |
|
if err != nil { |
|
return |
|
} |
|
|
|
rsp, err := c.client.ListExchangeTradeInstance(ctx, &pb.ReqListExchangeTradeInstance{ |
|
Exchanges: []pb.Exchange{pbExType}, |
|
}) |
|
if err != nil { |
|
return |
|
} |
|
for _, pbExInst := range rsp.ExchangeInsts { |
|
exInst := mapping.Proto2ExchangeTradeInstance(pbExInst) |
|
exInsts = append(exInsts, exInst) |
|
} |
|
return |
|
}
|
|
|