Skip to content

Commit

Permalink
Some review feedback.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Wilkie committed Sep 5, 2015
1 parent 15e25ed commit ad6702a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 74 deletions.
11 changes: 4 additions & 7 deletions probe/endpoint/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Reporter struct {
includeNAT bool
conntracker *Conntracker
natmapper *natmapper
revResolver *reverseResolver
revResolver *ReverseResolver
}

// SpyDuration is an exported prometheus metric
Expand Down Expand Up @@ -65,16 +65,13 @@ func NewReporter(hostID, hostName string, includeProcesses bool, useConntrack bo
log.Printf("Failed to start natMapper: %v", err)
}
}

revRes := newReverseResolver()

return &Reporter{
hostID: hostID,
hostName: hostName,
includeProcesses: includeProcesses,
conntracker: conntracker,
natmapper: natmapper,
revResolver: revRes,
revResolver: NewReverseResolver(),
}
}

Expand Down Expand Up @@ -152,7 +149,7 @@ func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr strin
)

// in case we have a reverse resolution for the IP, we can use it for the name...
if revRemoteName, err := r.revResolver.Get(remoteAddr, false); err == nil {
if revRemoteName, err := r.revResolver.Get(remoteAddr); err == nil {
remoteNode = remoteNode.AddMetadata(map[string]string{
"name": revRemoteName,
})
Expand Down Expand Up @@ -191,7 +188,7 @@ func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr strin
)

// in case we have a reverse resolution for the IP, we can use it for the name...
if revRemoteName, err := r.revResolver.Get(remoteAddr, false); err == nil {
if revRemoteName, err := r.revResolver.Get(remoteAddr); err == nil {
remoteNode = remoteNode.AddMetadata(map[string]string{
"name": revRemoteName,
})
Expand Down
43 changes: 17 additions & 26 deletions probe/endpoint/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,22 @@ const (

type revResFunc func(addr string) (names []string, err error)

type revResRequest struct {
address string
done chan struct{}
}

// ReverseResolver is a caching, reverse resolver
type reverseResolver struct {
addresses chan revResRequest
type ReverseResolver struct {

This comment has been minimized.

Copy link
@peterbourgon

peterbourgon Sep 5, 2015

Contributor

Why make it public?

This comment has been minimized.

Copy link
@tomwilkie

tomwilkie Sep 5, 2015

Contributor

Testing (to use test.Poll, the tests need to be in a different package, and therefore this needs to be public).

This comment has been minimized.

Copy link
@peterbourgon

peterbourgon Sep 6, 2015

Contributor

That's too bad.

addresses chan string
cache gcache.Cache
resolver revResFunc
Throttle <-chan time.Time // Made public for mocking
Resolver revResFunc
}

// NewReverseResolver starts a new reverse resolver that
// performs reverse resolutions and caches the result.
func newReverseResolver() *reverseResolver {
r := reverseResolver{
addresses: make(chan revResRequest, rAddrBacklog),
func NewReverseResolver() *ReverseResolver {
r := ReverseResolver{
addresses: make(chan string, rAddrBacklog),
cache: gcache.New(rAddrCacheLen).LRU().Expiration(rAddrCacheExpiration).Build(),
resolver: net.LookupAddr,
Throttle: time.Tick(time.Second / 10),
Resolver: net.LookupAddr,
}
go r.loop()
return &r
Expand All @@ -43,43 +40,37 @@ func newReverseResolver() *reverseResolver {
// Get the reverse resolution for an IP address if already in the cache,
// a gcache.NotFoundKeyError error otherwise.
// Note: it returns one of the possible names that can be obtained for that IP.
func (r *reverseResolver) Get(address string, wait bool) (string, error) {
func (r *ReverseResolver) Get(address string) (string, error) {
val, err := r.cache.Get(address)
if err == nil {
return val.(string), nil
}
if err == gcache.NotFoundKeyError {
request := revResRequest{address: address, done: make(chan struct{})}
// we trigger a asynchronous reverse resolution when not cached
select {
case r.addresses <- request:
if wait {
<-request.done
}
case r.addresses <- address:
default:
}
}
return "", err
}

func (r *reverseResolver) loop() {
throttle := time.Tick(time.Second / 10)
func (r *ReverseResolver) loop() {
for request := range r.addresses {
<-throttle // rate limit our DNS resolutions
<-r.Throttle // rate limit our DNS resolutions
// and check if the answer is already in the cache
if _, err := r.cache.Get(request.address); err == nil {
if _, err := r.cache.Get(request); err == nil {
continue
}
names, err := r.resolver(request.address)
names, err := r.Resolver(request)
if err == nil && len(names) > 0 {
name := strings.TrimRight(names[0], ".")
r.cache.Set(request.address, name)
r.cache.Set(request, name)
}
close(request.done)
}
}

// Stop the async reverse resolver
func (r *reverseResolver) Stop() {
func (r *ReverseResolver) Stop() {
close(r.addresses)
}
41 changes: 0 additions & 41 deletions probe/endpoint/resolver_internal_test.go

This file was deleted.

38 changes: 38 additions & 0 deletions probe/endpoint/resolver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package endpoint_test

import (
"errors"
"testing"
"time"

. "github.com/weaveworks/scope/probe/endpoint"
"github.com/weaveworks/scope/test"
)

func TestReverseResolver(t *testing.T) {
tests := map[string]string{
"1.2.3.4": "test.domain.name",
"4.3.2.1": "im.a.little.tea.pot",
}

revRes := NewReverseResolver()
defer revRes.Stop()

// use a mocked resolver function
revRes.Resolver = func(addr string) (names []string, err error) {
if name, ok := tests[addr]; ok {
return []string{name}, nil
}
return []string{}, errors.New("invalid IP")
}

// Up the rate limit so the test runs faster
revRes.Throttle = time.Tick(time.Millisecond)

for ip, hostname := range tests {
test.Poll(t, 100*time.Millisecond, hostname, func() interface{} {
result, _ := revRes.Get(ip)
return result
})
}
}

0 comments on commit ad6702a

Please sign in to comment.