mirror of https://github.com/Dreamacro/clash.git
Feature: reuse dns resolver cache when hot reload
This commit is contained in:
parent
b8ed738238
commit
a32ee13fc9
|
@ -146,6 +146,23 @@ func (c *LruCache) SetWithExpire(key interface{}, value interface{}, expires tim
|
|||
c.maybeDeleteOldest()
|
||||
}
|
||||
|
||||
// CloneTo clone and overwrite elements to another LruCache
|
||||
func (c *LruCache) CloneTo(n *LruCache) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
||||
n.lru = list.New()
|
||||
n.cache = make(map[interface{}]*list.Element)
|
||||
|
||||
for e := c.lru.Front(); e != nil; e = e.Next() {
|
||||
elm := e.Value.(*entry)
|
||||
n.cache[elm.key] = n.lru.PushBack(elm)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *LruCache) get(key interface{}) *entry {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
|
|
@ -164,3 +164,21 @@ func TestStale(t *testing.T) {
|
|||
assert.Equal(t, tenSecBefore, expires)
|
||||
assert.Equal(t, true, exist)
|
||||
}
|
||||
|
||||
func TestCloneTo(t *testing.T) {
|
||||
o := NewLRUCache(WithSize(10))
|
||||
o.Set("1", 1)
|
||||
o.Set("2", 2)
|
||||
|
||||
n := NewLRUCache(WithSize(2))
|
||||
n.Set("3", 3)
|
||||
n.Set("4", 4)
|
||||
|
||||
o.CloneTo(n)
|
||||
|
||||
assert.False(t, n.Exist("3"))
|
||||
assert.True(t, n.Exist("1"))
|
||||
|
||||
n.Set("5", 5)
|
||||
assert.False(t, n.Exist("1"))
|
||||
}
|
||||
|
|
|
@ -186,6 +186,11 @@ func (r *Resolver) IsFakeIP(ip net.IP) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// PatchCache overwrite lruCache to the new resolver
|
||||
func (r *Resolver) PatchCache(n *Resolver) {
|
||||
r.lruCache.CloneTo(n.lruCache)
|
||||
}
|
||||
|
||||
func (r *Resolver) batchExchange(clients []dnsClient, m *D.Msg) (msg *D.Msg, err error) {
|
||||
fast, ctx := picker.WithTimeout(context.Background(), time.Second*5)
|
||||
for _, client := range clients {
|
||||
|
|
|
@ -120,6 +120,14 @@ func updateDNS(c *config.DNS) {
|
|||
},
|
||||
Default: c.DefaultNameserver,
|
||||
})
|
||||
|
||||
// reuse cache of old resolver
|
||||
if resolver.DefaultResolver != nil {
|
||||
if o, ok := resolver.DefaultResolver.(*dns.Resolver); ok {
|
||||
o.PatchCache(r)
|
||||
}
|
||||
}
|
||||
|
||||
resolver.DefaultResolver = r
|
||||
tunnel.SetResolver(r)
|
||||
if err := dns.ReCreateServer(c.Listen, r); err != nil {
|
||||
|
|
Loading…
Reference in New Issue