generated from templates/go-generic
Dan Anglin
70faf8366a
- Added in-memory cache - Created new package for defining the types of the pokeapi API - Created an internal package for the client
85 lines
1.3 KiB
Go
85 lines
1.3 KiB
Go
package pokecache
|
|
|
|
import (
|
|
"maps"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Cache struct {
|
|
stopChan chan struct{}
|
|
mu *sync.Mutex
|
|
entries map[string]cacheEntry
|
|
interval time.Duration
|
|
}
|
|
|
|
type cacheEntry struct {
|
|
createdAt time.Time
|
|
val []byte
|
|
}
|
|
|
|
func NewCache(interval time.Duration) *Cache {
|
|
cache := Cache{
|
|
stopChan: make(chan struct{}),
|
|
mu: &sync.Mutex{},
|
|
entries: make(map[string]cacheEntry),
|
|
interval: interval,
|
|
}
|
|
|
|
go cache.readLoop()
|
|
|
|
return &cache
|
|
}
|
|
|
|
func (c *Cache) Add(key string, val []byte) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
entry := cacheEntry{
|
|
createdAt: time.Now(),
|
|
val: val,
|
|
}
|
|
|
|
c.entries[key] = entry
|
|
}
|
|
|
|
func (c *Cache) Get(key string) ([]byte, bool) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
value, exist := c.entries[key]
|
|
|
|
return value.val, exist
|
|
}
|
|
|
|
// func (c *Cache) Stop() {
|
|
// c.stopChan <- struct{}{}
|
|
// }
|
|
|
|
func (c *Cache) readLoop() {
|
|
ticker := time.NewTicker(c.interval)
|
|
defer ticker.Stop()
|
|
|
|
readloop:
|
|
for {
|
|
select {
|
|
case <-c.stopChan:
|
|
break readloop
|
|
case <-ticker.C:
|
|
c.cleanupEntries()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *Cache) cleanupEntries() {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
expiredTime := time.Now().Add(-c.interval)
|
|
|
|
for key := range maps.All(c.entries) {
|
|
if c.entries[key].createdAt.Before(expiredTime) {
|
|
delete(c.entries, key)
|
|
}
|
|
}
|
|
}
|