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() | |
| 		} | |
| 	}() | |
| }
 |