Merge pull request #25 from dbalan/memcached_backend_support
Memcached backend support
This commit is contained in:
commit
9e3c916046
87
cache.go
87
cache.go
|
@ -7,6 +7,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/bradfitz/gomemcache/memcache"
|
||||
"github.com/hoisie/redis"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
@ -35,10 +36,11 @@ func (e CacheIsFull) Error() string {
|
|||
}
|
||||
|
||||
type SerializerError struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e SerializerError) Error() string {
|
||||
return "Serializer error"
|
||||
return fmt.Sprintf("Serializer error: got %v", e.err)
|
||||
}
|
||||
|
||||
type Mesg struct {
|
||||
|
@ -50,8 +52,8 @@ type Cache interface {
|
|||
Get(key string) (Msg *dns.Msg, err error)
|
||||
Set(key string, Msg *dns.Msg) error
|
||||
Exists(key string) bool
|
||||
Remove(key string)
|
||||
Length() int
|
||||
Remove(key string) error
|
||||
Full() bool
|
||||
}
|
||||
|
||||
type MemoryCache struct {
|
||||
|
@ -91,10 +93,11 @@ func (c *MemoryCache) Set(key string, msg *dns.Msg) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *MemoryCache) Remove(key string) {
|
||||
func (c *MemoryCache) Remove(key string) error {
|
||||
c.mu.Lock()
|
||||
delete(c.Backend, key)
|
||||
c.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *MemoryCache) Exists(key string) bool {
|
||||
|
@ -118,6 +121,70 @@ func (c *MemoryCache) Full() bool {
|
|||
return c.Length() >= c.Maxcount
|
||||
}
|
||||
|
||||
/*
|
||||
Memcached backend
|
||||
*/
|
||||
|
||||
func NewMemcachedCache(servers []string, expire int32) *MemcachedCache {
|
||||
c := memcache.New(servers...)
|
||||
return &MemcachedCache{
|
||||
backend: c,
|
||||
expire: expire,
|
||||
}
|
||||
}
|
||||
|
||||
type MemcachedCache struct {
|
||||
backend *memcache.Client
|
||||
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 = msg.Pack()
|
||||
}
|
||||
if err != nil {
|
||||
err = SerializerError{err}
|
||||
}
|
||||
return m.backend.Set(&memcache.Item{Key: key, Value: val, Expiration: m.expire})
|
||||
}
|
||||
|
||||
func (m *MemcachedCache) Get(key string) (*dns.Msg, error) {
|
||||
var msg dns.Msg
|
||||
item, err := m.backend.Get(key)
|
||||
if err != nil {
|
||||
err = KeyNotFound{key}
|
||||
return &msg, err
|
||||
}
|
||||
err = msg.Unpack(item.Value)
|
||||
if err != nil {
|
||||
err = SerializerError{err}
|
||||
}
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -149,16 +216,18 @@ func KeyGen(q Question) string {
|
|||
return key
|
||||
}
|
||||
|
||||
/* we need to define marsheling to encode and decode
|
||||
*/
|
||||
type JsonSerializer struct {
|
||||
}
|
||||
|
||||
func (*JsonSerializer) Dumps(mesg *dns.Msg) (encoded []byte, err error) {
|
||||
encoded, err = json.Marshal(mesg)
|
||||
encoded, err = json.Marshal(*mesg)
|
||||
return
|
||||
}
|
||||
|
||||
func (*JsonSerializer) Loads(data []byte, mesg **dns.Msg) error {
|
||||
err := json.Unmarshal(data, mesg)
|
||||
return err
|
||||
|
||||
func (*JsonSerializer) Loads(data []byte) (*dns.Msg, error) {
|
||||
var mesg dns.Msg
|
||||
err := json.Unmarshal(data, &mesg)
|
||||
return &mesg, err
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ port = 6379
|
|||
db = 0
|
||||
password =""
|
||||
|
||||
[memcache]
|
||||
servers = ["127.0.0.1:11211"]
|
||||
|
||||
[log]
|
||||
stdout = true
|
||||
file = "./godns.log"
|
||||
|
@ -32,7 +35,7 @@ level = "INFO" #DEBUG | INFO |NOTICE | WARN | ERROR
|
|||
|
||||
|
||||
[cache]
|
||||
# backend option [memory|redis]
|
||||
# backend option [memory|memcache|redis]
|
||||
# redis backend not implemented yet
|
||||
backend = "memory"
|
||||
expire = 600 # 10 minutes
|
||||
|
|
|
@ -61,6 +61,13 @@ func NewHandler() *GODNSHandler {
|
|||
Expire: time.Duration(cacheConfig.Expire) * time.Second / 2,
|
||||
Maxcount: cacheConfig.Maxcount,
|
||||
}
|
||||
case "memcache":
|
||||
cache = NewMemcachedCache(
|
||||
settings.Memcache.Servers,
|
||||
int32(cacheConfig.Expire))
|
||||
negCache = NewMemcachedCache(
|
||||
settings.Memcache.Servers,
|
||||
int32(cacheConfig.Expire/2))
|
||||
case "redis":
|
||||
// cache = &MemoryCache{
|
||||
// Backend: make(map[string]*dns.Msg),
|
||||
|
|
|
@ -27,6 +27,7 @@ type Settings struct {
|
|||
Server DNSServerSettings `toml:"server"`
|
||||
ResolvConfig ResolvSettings `toml:"resolv"`
|
||||
Redis RedisSettings `toml:"redis"`
|
||||
Memcache MemcacheSettings `toml:"memcache"`
|
||||
Log LogSettings `toml:"log"`
|
||||
Cache CacheSettings `toml:"cache"`
|
||||
Hosts HostsSettings `toml:"hosts"`
|
||||
|
@ -50,6 +51,10 @@ type RedisSettings struct {
|
|||
Password string
|
||||
}
|
||||
|
||||
type MemcacheSettings struct {
|
||||
Servers []string
|
||||
}
|
||||
|
||||
func (s RedisSettings) Addr() string {
|
||||
return s.Host + ":" + strconv.Itoa(s.Port)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue