From 84d878c03d65c521793b279de7e9bdf4846928ab Mon Sep 17 00:00:00 2001 From: kenshin Date: Thu, 25 Jul 2013 00:09:07 +0800 Subject: [PATCH] cache add expire strategy --- README.MD | 17 ++++++++++++++++- cache.go | 53 +++++++++++++++++++++++++++++++++-------------------- handler.go | 15 ++++++++------- settings.go | 3 +-- 4 files changed, 58 insertions(+), 30 deletions(-) diff --git a/README.MD b/README.MD index c6967a3..3829c7c 100644 --- a/README.MD +++ b/README.MD @@ -15,7 +15,9 @@ Similar as [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) ,but support * Cache records save in memory or redis configurable -## Install & Running +## Install + +## Running @@ -46,6 +48,19 @@ If multi `namerserver` set at resolv.conf, the upsteam server will try in order Only the local memory storage backend implemented now. The redis backend is in todo list +``` +[cache] +backend = "memory" +expire = 600 # default expire time 10 minutes +maxcount = 100000 +``` + + +## TODO + +* The redis cache backend +* Update ttl + diff --git a/cache.go b/cache.go index 82da34c..9c2f823 100644 --- a/cache.go +++ b/cache.go @@ -39,69 +39,82 @@ func (e SerializerError) Error() string { return "Serializer error" } +type Mesg struct { + Msg *dns.Msg + Expire time.Time +} + type Cache interface { - Get(key string) (*dns.Msg, error) - Set(key string, mesg *dns.Msg) error + Get(key string) (Msg *dns.Msg, err error) + Set(key string, Msg *dns.Msg) error Exists(key string) bool Remove(key string) Length() int } type MemoryCache struct { - backend map[string]*dns.Msg - expire time.Duration - maxcount int + Backend map[string]Mesg + Expire time.Duration + Maxcount int } func (c *MemoryCache) Get(key string) (*dns.Msg, error) { - mesg, ok := c.backend[key] + mesg, ok := c.Backend[key] if !ok { return nil, KeyNotFound{key} } - return mesg, nil + if mesg.Expire.Before(time.Now()) { + c.Remove(key) + return nil, KeyExpired{key} + } + + return mesg.Msg, nil } -func (c *MemoryCache) Set(key string, mesg *dns.Msg) error { +func (c *MemoryCache) Set(key string, msg *dns.Msg) error { if c.Full() && !c.Exists(key) { return CacheIsFull{} } - c.backend[key] = mesg + + expire := time.Now().Add(c.Expire) + mesg := Mesg{msg, expire} + c.Backend[key] = mesg return nil } func (c *MemoryCache) Remove(key string) { - delete(c.backend, key) + delete(c.Backend, key) } func (c *MemoryCache) Exists(key string) bool { - _, ok := c.backend[key] + _, ok := c.Backend[key] return ok } func (c *MemoryCache) Length() int { - return len(c.backend) + return len(c.Backend) } func (c *MemoryCache) Full() bool { - // if maxcount is zero. the cache will never be full. - if c.maxcount == 0 { + // if Maxcount is zero. the cache will never be full. + if c.Maxcount == 0 { return false } - return c.Length() >= c.maxcount + return c.Length() >= c.Maxcount } /* -TODO: Redis cache backend +TODO: Redis cache Backend */ type RedisCache struct { - backend *redis.Client - serializer JsonSerializer - expire time.Duration - maxcount int + Backend *redis.Client + Serializer JsonSerializer + Expire time.Duration + Maxcount int } func (c *RedisCache) Get() { diff --git a/handler.go b/handler.go index adb7e69..53a70d2 100644 --- a/handler.go +++ b/handler.go @@ -2,6 +2,7 @@ package main import ( "github.com/miekg/dns" + "time" ) type Question struct { @@ -42,16 +43,16 @@ func NewHandler() *GODNSHandler { switch cacheConfig.Backend { case "memory": cache = &MemoryCache{ - backend: make(map[string]*dns.Msg), - expire: cacheConfig.Expire, - maxcount: cacheConfig.Maxcount, + Backend: make(map[string]Mesg), + Expire: time.Duration(cacheConfig.Expire) * time.Second, + Maxcount: cacheConfig.Maxcount, } case "redis": // cache = &MemoryCache{ - // backend: make(map[string]*dns.Msg), - // serializer: new(JsonSerializer), - // expire: cacheConfig.Expire, - // maxcount: cacheConfig.Maxcount, + // Backend: make(map[string]*dns.Msg), + // Expire: time.Duration(cacheConfig.Expire) * time.Second, + // Serializer: new(JsonSerializer), + // Maxcount: cacheConfig.Maxcount, // } panic("Redis cache backend not implement yet") default: diff --git a/settings.go b/settings.go index 43a365b..d3ff306 100644 --- a/settings.go +++ b/settings.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/BurntSushi/toml" "os" - "time" ) var ( @@ -45,7 +44,7 @@ type LogSettings struct { type CacheSettings struct { Backend string - Expire time.Duration + Expire int Maxcount int }