Files
crypto-price-bot/internal/data/market/trading_pairs.go
T
thuanle 914beea5ce Address PR #15 round 2: fail-closed admin guard, sync init, error reporting
1. /refresh now fail-closed: rejects all if ADMIN_CHAT_ID unset or invalid
2. Initial pair cache fill is synchronous — bot waits before accepting queries
3. /refresh reports failure when API fetch fails instead of always saying success

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

75 lines
1.7 KiB
Go

package market
import (
"context"
"time"
"github.com/rs/zerolog/log"
)
func (ms *MarketData) refreshTradingPairCache() error {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
spotInfo, err := ms.spotClient.NewExchangeInfoService().Do(ctx)
if err != nil {
log.Error().Err(err).Msg("Failed to fetch spot exchange info")
return err
}
futuresInfo, err := ms.futuresClient.NewExchangeInfoService().Do(ctx)
if err != nil {
log.Error().Err(err).Msg("Failed to fetch futures exchange info")
return err
}
ms.pairCacheMutex.Lock()
defer ms.pairCacheMutex.Unlock()
ms.spotPairs = make(map[string]bool, len(spotInfo.Symbols))
for _, s := range spotInfo.Symbols {
if s.Status == "TRADING" {
ms.spotPairs[s.Symbol] = true
}
}
ms.futuresPairs = make(map[string]bool, len(futuresInfo.Symbols))
for _, s := range futuresInfo.Symbols {
if s.Status == "TRADING" {
ms.futuresPairs[s.Symbol] = true
}
}
ms.lastPairCacheUpdate = time.Now()
log.Info().
Int("spot", len(ms.spotPairs)).
Int("futures", len(ms.futuresPairs)).
Msg("Trading pair cache refreshed")
return nil
}
func (ms *MarketData) pairCacheRefreshLoop() {
ms.refreshTradingPairCache()
ticker := time.NewTicker(time.Hour)
defer ticker.Stop()
for range ticker.C {
ms.refreshTradingPairCache()
}
}
func (ms *MarketData) IsSpotPair(symbol string) bool {
ms.pairCacheMutex.RLock()
defer ms.pairCacheMutex.RUnlock()
return ms.spotPairs[symbol]
}
func (ms *MarketData) IsFuturesPair(symbol string) bool {
ms.pairCacheMutex.RLock()
defer ms.pairCacheMutex.RUnlock()
return ms.futuresPairs[symbol]
}
func (ms *MarketData) RefreshTradingPairCache() error {
return ms.refreshTradingPairCache()
}