Files
remembos/internal/memory/service.go
T
2026-02-12 11:10:40 +03:00

71 lines
1.5 KiB
Go

package memory
import (
"context"
"log/slog"
"sync"
"time"
"git.vakhrushev.me/av/remembos/internal/search"
"git.vakhrushev.me/av/remembos/internal/storage"
)
// Service provides "one memory per day" with in-memory caching.
type Service struct {
selector *search.Selector
store *storage.Storage
loc *time.Location
logger *slog.Logger
mu sync.Mutex
cacheDay string // "2006-01-02"
cached *search.Memory
}
func NewService(selector *search.Selector, store *storage.Storage, loc *time.Location, logger *slog.Logger) *Service {
return &Service{
selector: selector,
store: store,
loc: loc,
logger: logger,
}
}
// GetTodayMemory returns the memory for today, caching the result.
func (s *Service) GetTodayMemory(ctx context.Context) (*search.Memory, error) {
today := time.Now().In(s.loc)
dayKey := today.Format("2006-01-02")
s.mu.Lock()
if s.cacheDay == dayKey && s.cached != nil {
mem := s.cached
s.mu.Unlock()
return mem, nil
}
s.mu.Unlock()
s.logger.Info("selecting new memory", "date", dayKey)
mem, err := s.selector.Select(ctx, today)
if err != nil {
return nil, err
}
if mem == nil {
s.logger.Warn("no memory found for today")
return nil, nil
}
if err := s.store.RecordShow(ctx, mem.Memo.Name, mem.Tier); err != nil {
s.logger.Error("failed to record show", "error", err)
// Non-fatal: still return the memory
}
s.mu.Lock()
s.cacheDay = dayKey
s.cached = mem
s.mu.Unlock()
return mem, nil
}