Feature: reuse dns resolver cache when hot reload
This commit is contained in:
parent
b8ed738238
commit
a32ee13fc9
4 changed files with 48 additions and 0 deletions
17
common/cache/lrucache.go
vendored
17
common/cache/lrucache.go
vendored
|
@ -146,6 +146,23 @@ func (c *LruCache) SetWithExpire(key interface{}, value interface{}, expires tim
|
||||||
c.maybeDeleteOldest()
|
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 {
|
func (c *LruCache) get(key interface{}) *entry {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
18
common/cache/lrucache_test.go
vendored
18
common/cache/lrucache_test.go
vendored
|
@ -164,3 +164,21 @@ func TestStale(t *testing.T) {
|
||||||
assert.Equal(t, tenSecBefore, expires)
|
assert.Equal(t, tenSecBefore, expires)
|
||||||
assert.Equal(t, true, exist)
|
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
|
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) {
|
func (r *Resolver) batchExchange(clients []dnsClient, m *D.Msg) (msg *D.Msg, err error) {
|
||||||
fast, ctx := picker.WithTimeout(context.Background(), time.Second*5)
|
fast, ctx := picker.WithTimeout(context.Background(), time.Second*5)
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
|
|
|
@ -120,6 +120,14 @@ func updateDNS(c *config.DNS) {
|
||||||
},
|
},
|
||||||
Default: c.DefaultNameserver,
|
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
|
resolver.DefaultResolver = r
|
||||||
tunnel.SetResolver(r)
|
tunnel.SetResolver(r)
|
||||||
if err := dns.ReCreateServer(c.Listen, r); err != nil {
|
if err := dns.ReCreateServer(c.Listen, r); err != nil {
|
||||||
|
|
Loading…
Reference in a new issue