69 lines
1.4 KiB
Go
69 lines
1.4 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type cache_stage[T any] struct {
|
|
cache map[storagekey]T
|
|
deleted map[storagekey]T
|
|
}
|
|
|
|
func make_cache_stage[T any]() *cache_stage[T] {
|
|
return &cache_stage[T]{
|
|
cache: make(map[storagekey]T),
|
|
deleted: make(map[storagekey]T),
|
|
}
|
|
}
|
|
|
|
type consumer_common[T any] struct {
|
|
lock sync.Mutex
|
|
ttl time.Duration
|
|
ctx context.Context
|
|
stages [2]*cache_stage[T]
|
|
startTime time.Time
|
|
onSessionInvalidated []func(InvalidatedSession)
|
|
}
|
|
|
|
func (c *consumer_common[T]) add_internal(sk storagekey, si T) {
|
|
c.stages[0].cache[sk] = si
|
|
delete(c.stages[0].deleted, sk)
|
|
c.stages[1].cache[sk] = si
|
|
delete(c.stages[1].deleted, sk)
|
|
}
|
|
|
|
func (c *consumer_common[T]) delete_internal(sk storagekey) (old T) {
|
|
if v, ok := c.stages[0].cache[sk]; ok {
|
|
old = v
|
|
c.stages[0].deleted[sk] = old
|
|
c.stages[1].deleted[sk] = old
|
|
|
|
delete(c.stages[0].cache, sk)
|
|
delete(c.stages[1].cache, sk)
|
|
} else if v, ok = c.stages[1].cache[sk]; ok {
|
|
old = v
|
|
c.stages[1].deleted[sk] = old
|
|
|
|
delete(c.stages[1].cache, sk)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (c *consumer_common[T]) delete(sk storagekey) T {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
|
|
return c.delete_internal(sk)
|
|
}
|
|
|
|
func (c *consumer_common[T]) changeStage() {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
|
|
c.stages[1] = c.stages[0]
|
|
c.stages[0] = make_cache_stage[T]()
|
|
}
|