Skip to content

Instantly share code, notes, and snippets.

@thomaspoignant
Last active July 17, 2023 23:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomaspoignant/f2c901911e81f3109fe64ad840b5d393 to your computer and use it in GitHub Desktop.
Save thomaspoignant/f2c901911e81f3109fe64ad840b5d393 to your computer and use it in GitHub Desktop.
GO periodically refreshing Cache implementation
package main
import (
"fmt"
"sync"
"time"
)
var mutex sync.RWMutex
var cache map[string]interface{}
func main() {
// init
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop() // stop the ticker
updaterChan := make(chan struct{})
defer close(updaterChan) // close the channel
mutex = sync.RWMutex{}
// cache initialization
cache = map[string]interface{}{
"key1": "value1",
"key2": "value2",
"key3": time.Now(),
}
// launch a go routine to update the cache in the background
go startUpdaterDaemon(ticker, updaterChan)
// Wait to see the updated cache
for i:=0;i<100;i++{
time.Sleep(1*time.Second)
value,_:=getCacheEntry("key3")
fmt.Println(value)
}
}
// startUpdaterDaemon is running in background and update key3 on the ticker.
func startUpdaterDaemon(ticker *time.Ticker, updaterChan chan struct{}) {
for {
select {
case <- ticker.C:
// update cache
mutex.Lock() // lock the cache before writing into it
cache["key3"] = time.Now()
mutex.Unlock() // unlock the cache before writing into it
case <-updaterChan:
// stop the daemon
return
}
}
}
// getCacheEntry return the value of a cache entry.
func getCacheEntry(key string) (interface{},error) {
mutex.RLock() // add a read lock before reading the cache
defer mutex.RUnlock() // release the read lock when reading is done
value, ok := cache[key]
if !ok{
return nil,fmt.Errorf("key not found in cache")
}
return value, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment