Files
crypto-price-bot/internal/data/market/spot_price.go
T
thuanle 440fa3bacd Fix concurrent map read/write race condition in MarketData
Add sync.RWMutex to protect future and spot price maps accessed by
WebSocket handlers (writers) and Telegram bot handlers (readers).
Also adds Alpha token support with caching.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 00:15:22 +07:00

60 lines
1.3 KiB
Go

package market
import (
"strconv"
"github.com/adshao/go-binance/v2"
"github.com/rs/zerolog/log"
)
func (ms *MarketData) GetSpotPrice(symbol string) (float64, bool) {
ms.mu.RLock()
p, ok := ms.spotPrice[symbol]
ms.mu.RUnlock()
if ok {
return p, true
}
// If not found, check if it's an Alpha token and ensure cache is loaded
ms.ensureAlphaCacheLoaded()
if ms.IsAlphaToken(symbol) {
if alphaToken, exists := ms.GetAlphaToken(symbol); exists {
price := alphaToken.GetPrice()
if price > 0 {
ms.mu.Lock()
ms.spotPrice[symbol] = price
ms.mu.Unlock()
return price, true
}
}
}
return 0, false
}
func (ms *MarketData) StartSpotWsMarkPrice() error {
_, _, err := binance.WsAllMarketsStatServe(ms.spotWsAllMarketsStatHandler, ms.spotWsErrHandler) //.WsAllMarkPriceServe(ms.futureWsMarkPriceHandler, ms.futureWsErrHandler)
if err != nil {
return err
}
return nil
}
func (ms *MarketData) spotWsAllMarketsStatHandler(event binance.WsAllMarketsStatEvent) {
ms.mu.Lock()
defer ms.mu.Unlock()
for _, priceEvent := range event {
price, err := strconv.ParseFloat(priceEvent.LastPrice, 64)
if err != nil {
continue
}
ms.spotPrice[priceEvent.Symbol] = price
}
}
func (ms *MarketData) spotWsErrHandler(err error) {
log.Debug().Err(err).Msg("Spot Ws Error. Restart socket")
_ = ms.StartSpotWsMarkPrice()
}