Skip to content

Commit 7a74d80

Browse files
authored
Merge pull request #43 from mageddo/feature/42
Local Resolution Optimizations
2 parents 2497e15 + d7e5623 commit 7a74d80

File tree

170 files changed

+143426
-275
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

170 files changed

+143426
-275
lines changed

RELEASE-NOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
### 2.2.0
2+
* Increased code coverage
3+
* Implementing cache at local hostnames and remote server resolution
4+
* Considering TTL to invalidate hostname cache for local resolution
5+
16
### 2.1.7
27
* All build and release process is made inside docker (no travis dependency)
38

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.8
1+
2.2.0

builder

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ case $1 in
8484

8585
rm -rf build/
8686
mkdir -p build/
87-
go test -cover=false -ldflags "-X github.com/mageddo/dns-proxy-server/flags.version=test" ./.../
87+
go test -race -cover -ldflags "-X github.com/mageddo/dns-proxy-server/flags.version=test" ./.../
8888
go build -v -o build/dns-proxy-server -ldflags "-X github.com/mageddo/dns-proxy-server/flags.version=$APP_VERSION"
8989
cp -r static build/
9090
cd build/

cache/cache.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package cache
2+
3+
type Cache interface {
4+
5+
Get(key interface{}) interface{}
6+
ContainsKey(key interface{}) bool
7+
Put(key, value interface{})
8+
PutIfAbsent(key, value interface{}) interface{}
9+
Remove(key interface{})
10+
Clear()
11+
12+
}

cache/lru/hashicorp/hashicorp.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package hashicorp
2+
3+
import "github.com/hashicorp/golang-lru"
4+
5+
type LRUCache struct {
6+
cache *lru.Cache
7+
}
8+
9+
func (c *LRUCache) Get(key interface{}) interface{} {
10+
v, _ := c.cache.Get(key)
11+
return v
12+
}
13+
14+
func (c *LRUCache) Put(key, value interface{}) {
15+
c.cache.Add(key, value)
16+
}

cache/lru/lru.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package lru
2+
3+
import (
4+
"github.com/mageddo/dns-proxy-server/cache"
5+
"github.com/hashicorp/golang-lru"
6+
"github.com/mageddo/dns-proxy-server/log"
7+
)
8+
9+
type LRUCache struct {
10+
Cache *lru.Cache
11+
}
12+
13+
func (c *LRUCache) ContainsKey(key interface{}) bool {
14+
return c.Cache.Contains(key)
15+
}
16+
17+
func (c *LRUCache) Get(key interface{}) interface{} {
18+
v, _ := c.Cache.Get(key)
19+
return v
20+
}
21+
22+
//
23+
// Put value in cache, it doesn't have guarantee of concurrency treat
24+
//
25+
func (c *LRUCache) Put(key, value interface{}) {
26+
c.Cache.Add(key, value)
27+
}
28+
29+
//
30+
// Check if value is already associated, if yes just return it, if not put the passed value and return nil
31+
// This method must be thread safe (atomic)
32+
//
33+
func (c *LRUCache) PutIfAbsent(key, value interface{}) interface{} {
34+
if ok, _ := c.Cache.ContainsOrAdd(key, value); ok {
35+
return c.Get(key)
36+
}
37+
return nil;
38+
}
39+
40+
func (c *LRUCache) Clear() {
41+
c.Cache.Purge()
42+
}
43+
44+
func (c *LRUCache) Remove(key interface{}) {
45+
c.Cache.Remove(key)
46+
}
47+
48+
//
49+
// Creates a LRU cache
50+
// size is the maximum size of the cache, -1 if it is unlimited
51+
//
52+
func New(size int) cache.Cache {
53+
c, err := lru.New(size)
54+
if err != nil {
55+
log.LOGGER.Errorf("status=cannot-create-cache, msg=%v", err)
56+
return nil;
57+
}
58+
return &LRUCache{c}
59+
}
60+
61+

cache/lru/lru_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package lru
2+
3+
import (
4+
"testing"
5+
"github.com/stretchr/testify/assert"
6+
)
7+
8+
func TestPutAndGetSuccess(t *testing.T){
9+
10+
cache := New(10);
11+
cache.Put("key1", "value1");
12+
13+
assert.Equal(t, "value1", cache.Get("key1").(string))
14+
15+
}
16+
17+
func TestPutAndGetSuccessSizeLimited(t *testing.T){
18+
19+
cache := New(2);
20+
cache.Put("key1", "value1");
21+
cache.Put("key2", "value2");
22+
cache.Put("key3", "value3");
23+
24+
assert.Nil(t, cache.Get("key1"))
25+
assert.Equal(t, "value2", cache.Get("key2").(string))
26+
assert.Equal(t, "value3", cache.Get("key3").(string))
27+
28+
}
29+
30+
func TestPutAndGeRemovingLeastUsed(t *testing.T){
31+
32+
cache := New(3);
33+
34+
cache.Put("key1", "value1");
35+
cache.Put("key2", "value2");
36+
cache.Put("key3", "value3");
37+
38+
39+
cache.Get("key2")
40+
cache.Get("key1")
41+
42+
cache.Put("key4", "value4");
43+
44+
45+
assert.Equal(t, "value1", cache.Get("key1"))
46+
assert.Equal(t, "value2", cache.Get("key2").(string))
47+
assert.Nil(t, cache.Get("key3"))
48+
assert.Equal(t, "value4", cache.Get("key4").(string))
49+
50+
}
51+
52+
53+
func TestPurge(t *testing.T){
54+
55+
cache := New(3);
56+
57+
cache.Put("key1", "value1");
58+
cache.Put("key2", "value2");
59+
60+
assert.Equal(t, "value1", cache.Get("key1"))
61+
assert.Equal(t, "value2", cache.Get("key2"))
62+
63+
cache.Clear()
64+
65+
assert.False(t, cache.ContainsKey("key1"))
66+
assert.False(t, cache.ContainsKey("key2"))
67+
68+
}
69+
70+
func TestRemove(t *testing.T){
71+
72+
cache := New(3);
73+
74+
cache.Put("key1", "value1");
75+
cache.Put("key2", "value2");
76+
77+
assert.Equal(t, "value1", cache.Get("key1"))
78+
assert.Equal(t, "value2", cache.Get("key2"))
79+
80+
cache.Remove("key2")
81+
82+
assert.True(t, cache.ContainsKey("key1"))
83+
assert.False(t, cache.ContainsKey("key2"))
84+
85+
}

cache/store/store.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package store
2+
3+
import (
4+
"github.com/mageddo/dns-proxy-server/cache/lru"
5+
"github.com/mageddo/dns-proxy-server/cache"
6+
)
7+
8+
var c cache.Cache;
9+
func init(){
10+
c = lru.New(43690); // about 1 MB considering HostnameVo struct
11+
}
12+
13+
//
14+
// Singleton cache
15+
//
16+
func GetInstance() cache.Cache {
17+
return c
18+
}

cache/timed/timedvalue.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package timed
2+
3+
import (
4+
"time"
5+
)
6+
7+
type TimedValue interface {
8+
Creation() time.Time
9+
Timeout() time.Duration
10+
Value() interface{}
11+
12+
//
13+
// Check if the value has expired
14+
// now current time to be compared with the Creation()
15+
//
16+
IsValid(now time.Time) bool
17+
18+
}
19+
20+
type timedValueImpl struct {
21+
creation time.Time
22+
timeout time.Duration
23+
value interface{}
24+
}
25+
26+
func(t *timedValueImpl) Creation() time.Time {
27+
return t.creation
28+
}
29+
30+
func(t *timedValueImpl) Timeout() time.Duration {
31+
return t.timeout
32+
}
33+
34+
func(t *timedValueImpl) Value() interface{} {
35+
return t.value
36+
}
37+
38+
func(t *timedValueImpl) IsValid(now time.Time) bool {
39+
return t.Timeout() > now.Sub(t.Creation())
40+
}
41+
42+
func NewTimedValue(value interface{}, creation time.Time, timeout time.Duration) TimedValue {
43+
return &timedValueImpl{creation:creation, value:value, timeout:timeout}
44+
}

cache/timed/timedvalue_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package timed
2+
3+
import (
4+
"testing"
5+
"time"
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestTimedValueImpl_IsValid(t *testing.T) {
10+
11+
current1, err := time.Parse("2006-01-02 15:04:05.999", "2017-07-19 17:00:00.300")
12+
assert.Nil(t, err)
13+
14+
current2, err := time.Parse("2006-01-02 15:04:05.999", "2017-07-19 17:00:00.700")
15+
assert.Nil(t, err)
16+
17+
expiredTime, err := time.Parse("2006-01-02 15:04:05.999", "2017-07-19 17:00:00.900")
18+
assert.Nil(t, err)
19+
20+
assert.True(t, NewTimedValue(1, current1, time.Duration(500 * time.Millisecond)).IsValid(current2))
21+
assert.False(t, NewTimedValue(1, current1, time.Duration(500 * time.Millisecond)).IsValid(expiredTime))
22+
23+
}

0 commit comments

Comments
 (0)