Chore: remove old cache implementation

This commit is contained in:
gVisor bot 2022-08-17 11:43:13 +08:00
parent 730f5b2d5f
commit 08f414e9c7
10 changed files with 26 additions and 205 deletions

106
common/cache/cache.go vendored
View file

@ -1,106 +0,0 @@
package cache
import (
"runtime"
"sync"
"time"
)
// Cache store element with a expired time
type Cache struct {
*cache
}
type cache struct {
mapping sync.Map
janitor *janitor
}
type element struct {
Expired time.Time
Payload any
}
// Put element in Cache with its ttl
func (c *cache) Put(key any, payload any, ttl time.Duration) {
c.mapping.Store(key, &element{
Payload: payload,
Expired: time.Now().Add(ttl),
})
}
// Get element in Cache, and drop when it expired
func (c *cache) Get(key any) any {
item, exist := c.mapping.Load(key)
if !exist {
return nil
}
elm := item.(*element)
// expired
if time.Since(elm.Expired) > 0 {
c.mapping.Delete(key)
return nil
}
return elm.Payload
}
// GetWithExpire element in Cache with Expire Time
func (c *cache) GetWithExpire(key any) (payload any, expired time.Time) {
item, exist := c.mapping.Load(key)
if !exist {
return
}
elm := item.(*element)
// expired
if time.Since(elm.Expired) > 0 {
c.mapping.Delete(key)
return
}
return elm.Payload, elm.Expired
}
func (c *cache) cleanup() {
c.mapping.Range(func(k, v any) bool {
key := k.(string)
elm := v.(*element)
if time.Since(elm.Expired) > 0 {
c.mapping.Delete(key)
}
return true
})
}
type janitor struct {
interval time.Duration
stop chan struct{}
}
func (j *janitor) process(c *cache) {
ticker := time.NewTicker(j.interval)
for {
select {
case <-ticker.C:
c.cleanup()
case <-j.stop:
ticker.Stop()
return
}
}
}
func stopJanitor(c *Cache) {
c.janitor.stop <- struct{}{}
}
// New return *Cache
func New(interval time.Duration) *Cache {
j := &janitor{
interval: interval,
stop: make(chan struct{}),
}
c := &cache{janitor: j}
go j.process(c)
C := &Cache{c}
runtime.SetFinalizer(C, stopJanitor)
return C
}

View file

@ -1,70 +0,0 @@
package cache
import (
"runtime"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestCache_Basic(t *testing.T) {
interval := 200 * time.Millisecond
ttl := 20 * time.Millisecond
c := New(interval)
c.Put("int", 1, ttl)
c.Put("string", "a", ttl)
i := c.Get("int")
assert.Equal(t, i.(int), 1, "should recv 1")
s := c.Get("string")
assert.Equal(t, s.(string), "a", "should recv 'a'")
}
func TestCache_TTL(t *testing.T) {
interval := 200 * time.Millisecond
ttl := 20 * time.Millisecond
now := time.Now()
c := New(interval)
c.Put("int", 1, ttl)
c.Put("int2", 2, ttl)
i := c.Get("int")
_, expired := c.GetWithExpire("int2")
assert.Equal(t, i.(int), 1, "should recv 1")
assert.True(t, now.Before(expired))
time.Sleep(ttl * 2)
i = c.Get("int")
j, _ := c.GetWithExpire("int2")
assert.Nil(t, i, "should recv nil")
assert.Nil(t, j, "should recv nil")
}
func TestCache_AutoCleanup(t *testing.T) {
interval := 10 * time.Millisecond
ttl := 15 * time.Millisecond
c := New(interval)
c.Put("int", 1, ttl)
time.Sleep(ttl * 2)
i := c.Get("int")
j, _ := c.GetWithExpire("int")
assert.Nil(t, i, "should recv nil")
assert.Nil(t, j, "should recv nil")
}
func TestCache_AutoGC(t *testing.T) {
sign := make(chan struct{})
go func() {
interval := 10 * time.Millisecond
ttl := 15 * time.Millisecond
c := New(interval)
c.Put("int", 1, ttl)
sign <- struct{}{}
}()
<-sign
runtime.GC()
}

View file

@ -64,8 +64,8 @@ type LruCache struct {
onEvict EvictCallback onEvict EvictCallback
} }
// NewLRUCache creates an LruCache // New creates an LruCache
func NewLRUCache(options ...Option) *LruCache { func New(options ...Option) *LruCache {
lc := &LruCache{ lc := &LruCache{
lru: list.New(), lru: list.New(),
cache: make(map[any]*list.Element), cache: make(map[any]*list.Element),

View file

@ -19,7 +19,7 @@ var entries = []struct {
} }
func TestLRUCache(t *testing.T) { func TestLRUCache(t *testing.T) {
c := NewLRUCache() c := New()
for _, e := range entries { for _, e := range entries {
c.Set(e.key, e.value) c.Set(e.key, e.value)
@ -45,7 +45,7 @@ func TestLRUCache(t *testing.T) {
} }
func TestLRUMaxAge(t *testing.T) { func TestLRUMaxAge(t *testing.T) {
c := NewLRUCache(WithAge(86400)) c := New(WithAge(86400))
now := time.Now().Unix() now := time.Now().Unix()
expected := now + 86400 expected := now + 86400
@ -88,7 +88,7 @@ func TestLRUMaxAge(t *testing.T) {
} }
func TestLRUpdateOnGet(t *testing.T) { func TestLRUpdateOnGet(t *testing.T) {
c := NewLRUCache(WithAge(86400), WithUpdateAgeOnGet()) c := New(WithAge(86400), WithUpdateAgeOnGet())
now := time.Now().Unix() now := time.Now().Unix()
expires := now + 86400/2 expires := now + 86400/2
@ -103,7 +103,7 @@ func TestLRUpdateOnGet(t *testing.T) {
} }
func TestMaxSize(t *testing.T) { func TestMaxSize(t *testing.T) {
c := NewLRUCache(WithSize(2)) c := New(WithSize(2))
// Add one expired entry // Add one expired entry
c.Set("foo", "bar") c.Set("foo", "bar")
_, ok := c.Get("foo") _, ok := c.Get("foo")
@ -117,7 +117,7 @@ func TestMaxSize(t *testing.T) {
} }
func TestExist(t *testing.T) { func TestExist(t *testing.T) {
c := NewLRUCache(WithSize(1)) c := New(WithSize(1))
c.Set(1, 2) c.Set(1, 2)
assert.True(t, c.Exist(1)) assert.True(t, c.Exist(1))
c.Set(2, 3) c.Set(2, 3)
@ -130,7 +130,7 @@ func TestEvict(t *testing.T) {
temp = key.(int) + value.(int) temp = key.(int) + value.(int)
} }
c := NewLRUCache(WithEvict(evict), WithSize(1)) c := New(WithEvict(evict), WithSize(1))
c.Set(1, 2) c.Set(1, 2)
c.Set(2, 3) c.Set(2, 3)
@ -138,7 +138,7 @@ func TestEvict(t *testing.T) {
} }
func TestSetWithExpire(t *testing.T) { func TestSetWithExpire(t *testing.T) {
c := NewLRUCache(WithAge(1)) c := New(WithAge(1))
now := time.Now().Unix() now := time.Now().Unix()
tenSecBefore := time.Unix(now-10, 0) tenSecBefore := time.Unix(now-10, 0)
@ -152,7 +152,7 @@ func TestSetWithExpire(t *testing.T) {
} }
func TestStale(t *testing.T) { func TestStale(t *testing.T) {
c := NewLRUCache(WithAge(1), WithStale(true)) c := New(WithAge(1), WithStale(true))
now := time.Now().Unix() now := time.Now().Unix()
tenSecBefore := time.Unix(now-10, 0) tenSecBefore := time.Unix(now-10, 0)
@ -165,11 +165,11 @@ func TestStale(t *testing.T) {
} }
func TestCloneTo(t *testing.T) { func TestCloneTo(t *testing.T) {
o := NewLRUCache(WithSize(10)) o := New(WithSize(10))
o.Set("1", 1) o.Set("1", 1)
o.Set("2", 2) o.Set("2", 2)
n := NewLRUCache(WithSize(2)) n := New(WithSize(2))
n.Set("3", 3) n.Set("3", 3)
n.Set("4", 4) n.Set("4", 4)

View file

@ -168,7 +168,7 @@ func New(options Options) (*Pool, error) {
} }
} else { } else {
pool.store = &memoryStore{ pool.store = &memoryStore{
cache: cache.NewLRUCache(cache.WithSize(options.Size * 2)), cache: cache.New(cache.WithSize(options.Size * 2)),
} }
} }

View file

@ -78,7 +78,7 @@ func NewEnhancer(cfg Config) *ResolverEnhancer {
if cfg.EnhancedMode != C.DNSNormal { if cfg.EnhancedMode != C.DNSNormal {
fakePool = cfg.Pool fakePool = cfg.Pool
mapping = cache.NewLRUCache(cache.WithSize(4096), cache.WithStale(true)) mapping = cache.New(cache.WithSize(4096), cache.WithStale(true))
} }
return &ResolverEnhancer{ return &ResolverEnhancer{

View file

@ -363,13 +363,13 @@ type Config struct {
func NewResolver(config Config) *Resolver { func NewResolver(config Config) *Resolver {
defaultResolver := &Resolver{ defaultResolver := &Resolver{
main: transform(config.Default, nil), main: transform(config.Default, nil),
lruCache: cache.NewLRUCache(cache.WithSize(4096), cache.WithStale(true)), lruCache: cache.New(cache.WithSize(4096), cache.WithStale(true)),
} }
r := &Resolver{ r := &Resolver{
ipv6: config.IPv6, ipv6: config.IPv6,
main: transform(config.Main, defaultResolver), main: transform(config.Main, defaultResolver),
lruCache: cache.NewLRUCache(cache.WithSize(4096), cache.WithStale(true)), lruCache: cache.New(cache.WithSize(4096), cache.WithStale(true)),
hosts: config.Hosts, hosts: config.Hosts,
} }

View file

@ -5,7 +5,6 @@ import (
"net" "net"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/Dreamacro/clash/adapter/inbound" "github.com/Dreamacro/clash/adapter/inbound"
"github.com/Dreamacro/clash/common/cache" "github.com/Dreamacro/clash/common/cache"
@ -15,7 +14,7 @@ import (
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
) )
func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.Cache) { func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.LruCache) {
client := newClient(c.RemoteAddr(), in) client := newClient(c.RemoteAddr(), in)
defer client.CloseIdleConnections() defer client.CloseIdleConnections()
@ -99,7 +98,7 @@ func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.Cache) {
conn.Close() conn.Close()
} }
func authenticate(request *http.Request, cache *cache.Cache) *http.Response { func authenticate(request *http.Request, cache *cache.LruCache) *http.Response {
authenticator := authStore.Authenticator() authenticator := authStore.Authenticator()
if authenticator != nil { if authenticator != nil {
credential := parseBasicProxyAuthorization(request) credential := parseBasicProxyAuthorization(request)
@ -109,11 +108,11 @@ func authenticate(request *http.Request, cache *cache.Cache) *http.Response {
return resp return resp
} }
var authed any authed, exist := cache.Get(credential)
if authed = cache.Get(credential); authed == nil { if !exist {
user, pass, err := decodeBasicProxyAuthorization(credential) user, pass, err := decodeBasicProxyAuthorization(credential)
authed = err == nil && authenticator.Verify(user, pass) authed = err == nil && authenticator.Verify(user, pass)
cache.Put(credential, authed, time.Minute) cache.Set(credential, authed)
} }
if !authed.(bool) { if !authed.(bool) {
log.Infoln("Auth failed from %s", request.RemoteAddr) log.Infoln("Auth failed from %s", request.RemoteAddr)

View file

@ -2,7 +2,6 @@ package http
import ( import (
"net" "net"
"time"
"github.com/Dreamacro/clash/common/cache" "github.com/Dreamacro/clash/common/cache"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
@ -40,9 +39,9 @@ func NewWithAuthenticate(addr string, in chan<- C.ConnContext, authenticate bool
return nil, err return nil, err
} }
var c *cache.Cache var c *cache.LruCache
if authenticate { if authenticate {
c = cache.New(time.Second * 30) c = cache.New(cache.WithAge(30))
} }
hl := &Listener{ hl := &Listener{

View file

@ -2,7 +2,6 @@ package mixed
import ( import (
"net" "net"
"time"
"github.com/Dreamacro/clash/common/cache" "github.com/Dreamacro/clash/common/cache"
N "github.com/Dreamacro/clash/common/net" N "github.com/Dreamacro/clash/common/net"
@ -16,7 +15,7 @@ import (
type Listener struct { type Listener struct {
listener net.Listener listener net.Listener
addr string addr string
cache *cache.Cache cache *cache.LruCache
closed bool closed bool
} }
@ -45,7 +44,7 @@ func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
ml := &Listener{ ml := &Listener{
listener: l, listener: l,
addr: addr, addr: addr,
cache: cache.New(30 * time.Second), cache: cache.New(cache.WithAge(30)),
} }
go func() { go func() {
for { for {
@ -63,7 +62,7 @@ func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
return ml, nil return ml, nil
} }
func handleConn(conn net.Conn, in chan<- C.ConnContext, cache *cache.Cache) { func handleConn(conn net.Conn, in chan<- C.ConnContext, cache *cache.LruCache) {
conn.(*net.TCPConn).SetKeepAlive(true) conn.(*net.TCPConn).SetKeepAlive(true)
bufConn := N.NewBufferedConn(conn) bufConn := N.NewBufferedConn(conn)