英文:
How to create a struct with auto scheduler?
问题
我的目标是自动清理map[string]time.Time
中的过期键,而不是手动循环检查。期望的结果是,key
会自动删除,而不是每隔1分钟进行检查和删除。
当前的解决方案是循环遍历并逐个检查
:
- 创建
var addrs = map[string]time.Time{}
- 启动一个goroutine,并依赖于
for {}
和time.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()
}
英文:
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()
}
答案1
得分: 2
你可以设置一个定时器,在你想要过期的项目时触发。不过,如果你计划存储许多项目,最好避免使用定时器,因为它需要消耗更多的内存来存储等待定时器触发的goroutine。
你可以在这里找到我创建的简单示例:
https://go.dev/play/p/cXdTXKUwJcf
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// 初始化缓存
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("存储键 %s,过期时间为 %s\n", key, val)
c.addrs.Store(key, val)
ticker := time.NewTicker(val.Sub(time.Now()))
go func() {
<-ticker.C
fmt.Printf("删除键 %s\n", key)
c.addrs.Delete(key)
}()
}
英文:
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)
}()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论