My goal is to clean the map[string]time.Time
from expired keys automatically instead of manual loop check. The expected result is that the key
automatically delete itself instead of getting checked and deleted every 1 minute.
The current solution is do a loop and check it one by one
:
- create the
var addrs = map[string]time.Time{}
- start a goroutine and rely on
for {}
andtime.Sleep()
.
var addrs = map[string]time.Time{}
func StartCleanExpiredAddrs() {
for {
time.Sleep(1 * time.Minute)
for addr, val := range addrs {
if time.Now().After(val) {
delete(addrs, addr)
}
}
}
}
func main() {
go StartCleanExpiredAddrs()
}
CodePudding user response:
One thing that you could do is set up a timer that will tick when you want to expire the item. You should avoid this though if you are planning to store many items because it will need to consume more memory to store the goroutine that will be waiting for the timer Tick.
you can find the simple example I created here: https://go.dev/play/p/cXdTXKUwJcf
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// init cache
cache := NewCacheWithExpiry()
cache.addItem("key1", time.Now().Add(time.Second*5))
cache.addItem("key2", time.Now().Add(time.Second*3))
time.Sleep(time.Second*10)
}
type customCacheWithExpiry struct {
addrs sync.Map
}
func NewCacheWithExpiry() *customCacheWithExpiry{
return &customCacheWithExpiry{
addrs: sync.Map{},
}
}
func (c *customCacheWithExpiry) addItem(key string, val time.Time){
fmt.Printf("storing key %s which expires at %s\n",key,val)
c.addrs.Store(key, val)
ticker := time.NewTicker(val.Sub(time.Now()))
go func() {
<-ticker.C
fmt.Printf("deleting key %s\n", key)
c.addrs.Delete(key)
}()
}