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.
80 lines
1.6 KiB
80 lines
1.6 KiB
package protocol
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// ResponseCache caches API responses to reduce CPU usage for repeated requests
|
|
type ResponseCache struct {
|
|
mu sync.RWMutex
|
|
cache map[string]*cacheEntry
|
|
ttl time.Duration
|
|
}
|
|
|
|
type cacheEntry struct {
|
|
response []byte
|
|
timestamp time.Time
|
|
}
|
|
|
|
// NewResponseCache creates a new response cache with the specified TTL
|
|
func NewResponseCache(ttl time.Duration) *ResponseCache {
|
|
return &ResponseCache{
|
|
cache: make(map[string]*cacheEntry),
|
|
ttl: ttl,
|
|
}
|
|
}
|
|
|
|
// Get retrieves a cached response if it exists and hasn't expired
|
|
func (c *ResponseCache) Get(key string) ([]byte, bool) {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
entry, exists := c.cache[key]
|
|
if !exists {
|
|
return nil, false
|
|
}
|
|
|
|
// Check if entry has expired
|
|
if time.Since(entry.timestamp) > c.ttl {
|
|
return nil, false
|
|
}
|
|
|
|
return entry.response, true
|
|
}
|
|
|
|
// Put stores a response in the cache
|
|
func (c *ResponseCache) Put(key string, response []byte) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
c.cache[key] = &cacheEntry{
|
|
response: response,
|
|
timestamp: time.Now(),
|
|
}
|
|
}
|
|
|
|
// Cleanup removes expired entries from the cache
|
|
func (c *ResponseCache) Cleanup() {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
now := time.Now()
|
|
for key, entry := range c.cache {
|
|
if now.Sub(entry.timestamp) > c.ttl {
|
|
delete(c.cache, key)
|
|
}
|
|
}
|
|
}
|
|
|
|
// StartCleanupLoop starts a background goroutine to periodically clean up expired entries
|
|
func (c *ResponseCache) StartCleanupLoop(interval time.Duration) {
|
|
go func() {
|
|
ticker := time.NewTicker(interval)
|
|
defer ticker.Stop()
|
|
|
|
for range ticker.C {
|
|
c.Cleanup()
|
|
}
|
|
}()
|
|
}
|