SHA256
95 lines
2.0 KiB
Go
95 lines
2.0 KiB
Go
package service
|
|
|
|
import (
|
|
"ashareview-server/model"
|
|
"ashareview-server/repository"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type cacheEntry[T any] struct {
|
|
data T
|
|
expires time.Time
|
|
}
|
|
|
|
type DashboardService struct {
|
|
repo *repository.StockRepo
|
|
mu sync.RWMutex
|
|
summary *cacheEntry[*model.DashboardSummary]
|
|
daily map[int]*cacheEntry[[]model.DailySummary]
|
|
consec *cacheEntry[[]model.ConsecutiveLimit]
|
|
}
|
|
|
|
func NewDashboardService(repo *repository.StockRepo) *DashboardService {
|
|
return &DashboardService{repo: repo, daily: make(map[int]*cacheEntry[[]model.DailySummary])}
|
|
}
|
|
|
|
const cacheTTL = 3 * time.Minute
|
|
|
|
func (s *DashboardService) GetSummary() (*model.DashboardSummary, error) {
|
|
s.mu.RLock()
|
|
if s.summary != nil && time.Now().Before(s.summary.expires) {
|
|
data := s.summary.data
|
|
s.mu.RUnlock()
|
|
return data, nil
|
|
}
|
|
s.mu.RUnlock()
|
|
|
|
date, err := s.repo.GetLatestTradeDate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
summary, err := s.repo.GetSummaryByDate(date)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.mu.Lock()
|
|
s.summary = &cacheEntry[*model.DashboardSummary]{data: summary, expires: time.Now().Add(cacheTTL)}
|
|
s.mu.Unlock()
|
|
|
|
return summary, nil
|
|
}
|
|
|
|
func (s *DashboardService) GetDailySummary(days int) ([]model.DailySummary, error) {
|
|
s.mu.RLock()
|
|
if e, ok := s.daily[days]; ok && time.Now().Before(e.expires) {
|
|
data := e.data
|
|
s.mu.RUnlock()
|
|
return data, nil
|
|
}
|
|
s.mu.RUnlock()
|
|
|
|
data, err := s.repo.GetDailySummary(days)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.mu.Lock()
|
|
s.daily[days] = &cacheEntry[[]model.DailySummary]{data: data, expires: time.Now().Add(cacheTTL)}
|
|
s.mu.Unlock()
|
|
|
|
return data, nil
|
|
}
|
|
|
|
func (s *DashboardService) GetConsecutiveLimits() ([]model.ConsecutiveLimit, error) {
|
|
s.mu.RLock()
|
|
if s.consec != nil && time.Now().Before(s.consec.expires) {
|
|
data := s.consec.data
|
|
s.mu.RUnlock()
|
|
return data, nil
|
|
}
|
|
s.mu.RUnlock()
|
|
|
|
data, err := s.repo.GetConsecutiveLimits()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.mu.Lock()
|
|
s.consec = &cacheEntry[[]model.ConsecutiveLimit]{data: data, expires: time.Now().Add(cacheTTL)}
|
|
s.mu.Unlock()
|
|
|
|
return data, nil
|
|
}
|