|
|
@@ -3,17 +3,22 @@ package local
|
|
|
import (
|
|
|
"strings"
|
|
|
"sync"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
type Cache struct {
|
|
|
- namespace string
|
|
|
- syncMap *sync.Map
|
|
|
+ namespace string
|
|
|
+ syncMap *sync.Map
|
|
|
+ expireRoutineDoneChannelsMutex *sync.Mutex
|
|
|
+ expireRoutineDoneChannels []chan any
|
|
|
}
|
|
|
|
|
|
func New(namespace string) *Cache {
|
|
|
return &Cache{
|
|
|
- namespace: namespace,
|
|
|
- syncMap: new(sync.Map),
|
|
|
+ namespace: namespace,
|
|
|
+ syncMap: new(sync.Map),
|
|
|
+ expireRoutineDoneChannelsMutex: new(sync.Mutex),
|
|
|
+ expireRoutineDoneChannels: make([]chan any, 0),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -22,11 +27,76 @@ func Destroy(cache *Cache) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ cache.expireRoutineDoneChannelsMutex.Lock()
|
|
|
+
|
|
|
+ for _, doneChan := range cache.expireRoutineDoneChannels {
|
|
|
+ doneChan <- nil
|
|
|
+ close(doneChan)
|
|
|
+ doneChan = nil
|
|
|
+ }
|
|
|
+
|
|
|
+ cache.expireRoutineDoneChannels = nil
|
|
|
+
|
|
|
+ cache.expireRoutineDoneChannelsMutex.Unlock()
|
|
|
+
|
|
|
cache.syncMap = nil
|
|
|
}
|
|
|
|
|
|
-func (cache *Cache) Set(key string, value string) error {
|
|
|
+func (cache *Cache) Set(key string, value string, expireSec int64) error {
|
|
|
cache.syncMap.Store(cache.key2CacheKey(key), value)
|
|
|
+
|
|
|
+ if expireSec != 0 {
|
|
|
+ doneChan := make(chan any)
|
|
|
+
|
|
|
+ cache.expireRoutineDoneChannelsMutex.Lock()
|
|
|
+
|
|
|
+ if cache.expireRoutineDoneChannels != nil {
|
|
|
+ cache.expireRoutineDoneChannels = append(cache.expireRoutineDoneChannels, doneChan)
|
|
|
+ }
|
|
|
+
|
|
|
+ cache.expireRoutineDoneChannelsMutex.Unlock()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ timer := time.NewTimer(time.Second * time.Duration(expireSec))
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ timer.Stop()
|
|
|
+
|
|
|
+ cache.expireRoutineDoneChannelsMutex.Lock()
|
|
|
+
|
|
|
+ if cache.expireRoutineDoneChannels != nil {
|
|
|
+ findIndex := -1
|
|
|
+
|
|
|
+ for i, savedDoneChan := range cache.expireRoutineDoneChannels {
|
|
|
+ if savedDoneChan == doneChan {
|
|
|
+ findIndex = i
|
|
|
+ close(savedDoneChan)
|
|
|
+ savedDoneChan = nil
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if findIndex != -1 {
|
|
|
+ cache.expireRoutineDoneChannels =
|
|
|
+ append(cache.expireRoutineDoneChannels[:findIndex], cache.expireRoutineDoneChannels[findIndex+1:]...)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ cache.expireRoutineDoneChannelsMutex.Unlock()
|
|
|
+ }()
|
|
|
+
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case <-timer.C:
|
|
|
+ cache.syncMap.Delete(cache.key2CacheKey(key))
|
|
|
+ return
|
|
|
+ case <-doneChan:
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ }
|
|
|
+
|
|
|
return nil
|
|
|
}
|
|
|
|