Add intial memcache support.
FIXME: serialization needs work.
This commit is contained in:
parent
b541f6e371
commit
8c4b338257
87
cache.go
87
cache.go
@ -7,6 +7,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bradfitz/gomemcache/memcache"
|
||||||
"github.com/hoisie/redis"
|
"github.com/hoisie/redis"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
@ -50,8 +51,13 @@ type Cache interface {
|
|||||||
Get(key string) (Msg *dns.Msg, err error)
|
Get(key string) (Msg *dns.Msg, err error)
|
||||||
Set(key string, Msg *dns.Msg) error
|
Set(key string, Msg *dns.Msg) error
|
||||||
Exists(key string) bool
|
Exists(key string) bool
|
||||||
Remove(key string)
|
Remove(key string) error
|
||||||
Length() int
|
Full() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Serializer interface {
|
||||||
|
Loads([]byte) (*dns.Msg, error)
|
||||||
|
Dumps(*dns.Msg) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemoryCache struct {
|
type MemoryCache struct {
|
||||||
@ -91,10 +97,11 @@ func (c *MemoryCache) Set(key string, msg *dns.Msg) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MemoryCache) Remove(key string) {
|
func (c *MemoryCache) Remove(key string) error {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
delete(c.Backend, key)
|
delete(c.Backend, key)
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MemoryCache) Exists(key string) bool {
|
func (c *MemoryCache) Exists(key string) bool {
|
||||||
@ -118,6 +125,68 @@ func (c *MemoryCache) Full() bool {
|
|||||||
return c.Length() >= c.Maxcount
|
return c.Length() >= c.Maxcount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Memcached backend
|
||||||
|
*/
|
||||||
|
|
||||||
|
func NewMemcachedCache(servers []string, expire int32) *MemcachedCache {
|
||||||
|
c := memcache.New(servers...)
|
||||||
|
return &MemcachedCache{
|
||||||
|
backend: c,
|
||||||
|
serializer: &JsonSerializer{},
|
||||||
|
expire: expire,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemcachedCache struct {
|
||||||
|
backend *memcache.Client
|
||||||
|
serializer Serializer
|
||||||
|
expire int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemcachedCache) Set(key string, msg *dns.Msg) error {
|
||||||
|
var val []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// handle cases for negacache where it sets nil values
|
||||||
|
if msg == nil {
|
||||||
|
val = []byte("nil")
|
||||||
|
} else {
|
||||||
|
val, err = m.serializer.Dumps(msg)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return m.backend.Set(&memcache.Item{Key: key, Value: val, Expiration: m.expire})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemcachedCache) Get(key string) (msg *dns.Msg, err error) {
|
||||||
|
item, err := m.backend.Get(key)
|
||||||
|
if err != nil {
|
||||||
|
err = KeyNotFound{key}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg, err = m.serializer.Loads(item.Value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemcachedCache) Exists(key string) bool {
|
||||||
|
_, err := m.backend.Get(key)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemcachedCache) Remove(key string) error {
|
||||||
|
return m.backend.Delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemcachedCache) Full() bool {
|
||||||
|
// memcache is never full (LRU)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Redis cache Backend
|
TODO: Redis cache Backend
|
||||||
*/
|
*/
|
||||||
@ -149,16 +218,18 @@ func KeyGen(q Question) string {
|
|||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we need to define marsheling to encode and decode
|
||||||
|
*/
|
||||||
type JsonSerializer struct {
|
type JsonSerializer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*JsonSerializer) Dumps(mesg *dns.Msg) (encoded []byte, err error) {
|
func (*JsonSerializer) Dumps(mesg *dns.Msg) (encoded []byte, err error) {
|
||||||
encoded, err = json.Marshal(mesg)
|
encoded, err = json.Marshal(*mesg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*JsonSerializer) Loads(data []byte, mesg **dns.Msg) error {
|
func (*JsonSerializer) Loads(data []byte) (*dns.Msg, error) {
|
||||||
err := json.Unmarshal(data, mesg)
|
var mesg dns.Msg
|
||||||
return err
|
err := json.Unmarshal(data, &mesg)
|
||||||
|
return &mesg, err
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ servers = ["127.0.0.1:11211"]
|
|||||||
[log]
|
[log]
|
||||||
stdout = true
|
stdout = true
|
||||||
file = "./godns.log"
|
file = "./godns.log"
|
||||||
level = "INFO" #DEBUG | INFO |NOTICE | WARN | ERROR
|
level = "DEBUG" #DEBUG | INFO |NOTICE | WARN | ERROR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ level = "INFO" #DEBUG | INFO |NOTICE | WARN | ERROR
|
|||||||
# backend option [memory|memcache|redis]
|
# backend option [memory|memcache|redis]
|
||||||
# redis backend not implemented yet
|
# redis backend not implemented yet
|
||||||
backend = "memory"
|
backend = "memory"
|
||||||
expire = 600 # 10 minutes
|
expire = 6000 # 10 minutes
|
||||||
maxcount = 0 #If set zero. The Sum of cache itmes will be unlimit.
|
maxcount = 0 #If set zero. The Sum of cache itmes will be unlimit.
|
||||||
|
|
||||||
[hosts]
|
[hosts]
|
||||||
|
@ -61,6 +61,13 @@ func NewHandler() *GODNSHandler {
|
|||||||
Expire: time.Duration(cacheConfig.Expire) * time.Second / 2,
|
Expire: time.Duration(cacheConfig.Expire) * time.Second / 2,
|
||||||
Maxcount: cacheConfig.Maxcount,
|
Maxcount: cacheConfig.Maxcount,
|
||||||
}
|
}
|
||||||
|
case "memcache":
|
||||||
|
cache = NewMemcachedCache(
|
||||||
|
settings.Memcache.Servers,
|
||||||
|
int32(cacheConfig.Expire))
|
||||||
|
negCache = NewMemcachedCache(
|
||||||
|
settings.Memcache.Servers,
|
||||||
|
int32(cacheConfig.Expire/2))
|
||||||
case "redis":
|
case "redis":
|
||||||
// cache = &MemoryCache{
|
// cache = &MemoryCache{
|
||||||
// Backend: make(map[string]*dns.Msg),
|
// Backend: make(map[string]*dns.Msg),
|
||||||
|
Loading…
Reference in New Issue
Block a user