cache add expire strategy

This commit is contained in:
kenshin 2013-07-25 00:09:07 +08:00
parent 01705a5019
commit 84d878c03d
4 changed files with 58 additions and 30 deletions

View File

@ -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 * 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 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

View File

@ -39,69 +39,82 @@ func (e SerializerError) Error() string {
return "Serializer error" return "Serializer error"
} }
type Mesg struct {
Msg *dns.Msg
Expire time.Time
}
type Cache interface { type Cache interface {
Get(key string) (*dns.Msg, error) Get(key string) (Msg *dns.Msg, err error)
Set(key string, mesg *dns.Msg) error Set(key string, Msg *dns.Msg) error
Exists(key string) bool Exists(key string) bool
Remove(key string) Remove(key string)
Length() int Length() int
} }
type MemoryCache struct { type MemoryCache struct {
backend map[string]*dns.Msg Backend map[string]Mesg
expire time.Duration Expire time.Duration
maxcount int Maxcount int
} }
func (c *MemoryCache) Get(key string) (*dns.Msg, error) { func (c *MemoryCache) Get(key string) (*dns.Msg, error) {
mesg, ok := c.backend[key] mesg, ok := c.Backend[key]
if !ok { if !ok {
return nil, KeyNotFound{key} 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) { if c.Full() && !c.Exists(key) {
return CacheIsFull{} return CacheIsFull{}
} }
c.backend[key] = mesg
expire := time.Now().Add(c.Expire)
mesg := Mesg{msg, expire}
c.Backend[key] = mesg
return nil return nil
} }
func (c *MemoryCache) Remove(key string) { func (c *MemoryCache) Remove(key string) {
delete(c.backend, key) delete(c.Backend, key)
} }
func (c *MemoryCache) Exists(key string) bool { func (c *MemoryCache) Exists(key string) bool {
_, ok := c.backend[key] _, ok := c.Backend[key]
return ok return ok
} }
func (c *MemoryCache) Length() int { func (c *MemoryCache) Length() int {
return len(c.backend) return len(c.Backend)
} }
func (c *MemoryCache) Full() bool { func (c *MemoryCache) Full() bool {
// if maxcount is zero. the cache will never be full. // if Maxcount is zero. the cache will never be full.
if c.maxcount == 0 { if c.Maxcount == 0 {
return false return false
} }
return c.Length() >= c.maxcount return c.Length() >= c.Maxcount
} }
/* /*
TODO: Redis cache backend TODO: Redis cache Backend
*/ */
type RedisCache struct { type RedisCache struct {
backend *redis.Client Backend *redis.Client
serializer JsonSerializer Serializer JsonSerializer
expire time.Duration Expire time.Duration
maxcount int Maxcount int
} }
func (c *RedisCache) Get() { func (c *RedisCache) Get() {

View File

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/miekg/dns" "github.com/miekg/dns"
"time"
) )
type Question struct { type Question struct {
@ -42,16 +43,16 @@ func NewHandler() *GODNSHandler {
switch cacheConfig.Backend { switch cacheConfig.Backend {
case "memory": case "memory":
cache = &MemoryCache{ cache = &MemoryCache{
backend: make(map[string]*dns.Msg), Backend: make(map[string]Mesg),
expire: cacheConfig.Expire, Expire: time.Duration(cacheConfig.Expire) * time.Second,
maxcount: cacheConfig.Maxcount, Maxcount: cacheConfig.Maxcount,
} }
case "redis": case "redis":
// cache = &MemoryCache{ // cache = &MemoryCache{
// backend: make(map[string]*dns.Msg), // Backend: make(map[string]*dns.Msg),
// serializer: new(JsonSerializer), // Expire: time.Duration(cacheConfig.Expire) * time.Second,
// expire: cacheConfig.Expire, // Serializer: new(JsonSerializer),
// maxcount: cacheConfig.Maxcount, // Maxcount: cacheConfig.Maxcount,
// } // }
panic("Redis cache backend not implement yet") panic("Redis cache backend not implement yet")
default: default:

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"os" "os"
"time"
) )
var ( var (
@ -45,7 +44,7 @@ type LogSettings struct {
type CacheSettings struct { type CacheSettings struct {
Backend string Backend string
Expire time.Duration Expire int
Maxcount int Maxcount int
} }