From 88a9bf04fd822f27aba685c0a34c3afae8579ae1 Mon Sep 17 00:00:00 2001 From: Brian Tiger Chow Date: Mon, 15 Dec 2014 20:30:18 -0800 Subject: [PATCH] fix: routing mock accuracy routing interface doesn't wait for value to appear in network, but value doesn't appear in network until time as passed License: MIT Signed-off-by: Brian Tiger Chow --- mock/client.go | 2 ++ mock/interface.go | 20 ++++++++++++++++---- mock/mockrouting_test.go | 37 ++++++++++++++++++++++++++++++++++++- mock/server.go | 30 +++++++++++++++++++----------- 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/mock/client.go b/mock/client.go index f4702aa..444a4b9 100644 --- a/mock/client.go +++ b/mock/client.go @@ -67,6 +67,8 @@ func (c *client) FindProvidersAsync(ctx context.Context, k u.Key, max int) <-cha return out } +// Provide returns once the message is on the network. Value is not necessarily +// visible yet. func (c *client) Provide(_ context.Context, key u.Key) error { return c.server.Announce(c.peer, key) } diff --git a/mock/interface.go b/mock/interface.go index e84a9ba..6397362 100644 --- a/mock/interface.go +++ b/mock/interface.go @@ -28,13 +28,25 @@ type Client interface { // NewServer returns a mockrouting Server func NewServer() Server { - return NewServerWithDelay(delay.Fixed(0)) + return NewServerWithDelay(DelayConfig{ + ValueVisibility: delay.Fixed(0), + Query: delay.Fixed(0), + }) } // NewServerWithDelay returns a mockrouting Server with a delay! -func NewServerWithDelay(d delay.D) Server { +func NewServerWithDelay(conf DelayConfig) Server { return &s{ - providers: make(map[u.Key]peer.Map), - delay: d, + providers: make(map[u.Key]map[u.Key]providerRecord), + delayConf: conf, } } + +type DelayConfig struct { + // ValueVisibility is the time it takes for a value to be visible in the network + // FIXME there _must_ be a better term for this + ValueVisibility delay.D + + // Query is the time it takes to receive a response from a routing query + Query delay.D +} diff --git a/mock/mockrouting_test.go b/mock/mockrouting_test.go index 3f9bfab..6700cd8 100644 --- a/mock/mockrouting_test.go +++ b/mock/mockrouting_test.go @@ -3,10 +3,12 @@ package mockrouting import ( "bytes" "testing" + "time" context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" - "github.com/jbenet/go-ipfs/peer" + peer "github.com/jbenet/go-ipfs/peer" u "github.com/jbenet/go-ipfs/util" + delay "github.com/jbenet/go-ipfs/util/delay" testutil "github.com/jbenet/go-ipfs/util/testutil" ) @@ -129,3 +131,36 @@ func TestCanceledContext(t *testing.T) { t.Fatal("Context cancel had no effect") } } + +func TestValidAfter(t *testing.T) { + + var p = testutil.NewPeerWithID(peer.ID([]byte("the peer id"))) + var key = u.Key("mock key") + var ctx = context.Background() + conf := DelayConfig{ + ValueVisibility: delay.Fixed(1 * time.Hour), + Query: delay.Fixed(0), + } + + rs := NewServerWithDelay(conf) + + rs.Client(p).Provide(ctx, key) + + var providers []peer.Peer + providers, err := rs.Client(p).FindProviders(ctx, key) + if err != nil { + t.Fatal(err) + } + if len(providers) > 0 { + t.Fail() + } + + conf.ValueVisibility.Set(0) + providers, err = rs.Client(p).FindProviders(ctx, key) + if err != nil { + t.Fatal(err) + } + if len(providers) != 1 { + t.Fail() + } +} diff --git a/mock/server.go b/mock/server.go index 3e189d9..e176c7a 100644 --- a/mock/server.go +++ b/mock/server.go @@ -3,11 +3,11 @@ package mockrouting import ( "math/rand" "sync" + "time" ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore" peer "github.com/jbenet/go-ipfs/peer" u "github.com/jbenet/go-ipfs/util" - delay "github.com/jbenet/go-ipfs/util/delay" ) // server is the mockrouting.Client's private interface to the routing server @@ -20,39 +20,47 @@ type server interface { // s is an implementation of the private server interface type s struct { - delay delay.D + delayConf DelayConfig lock sync.RWMutex - providers map[u.Key]peer.Map + providers map[u.Key]map[u.Key]providerRecord } -func (rs *s) Announce(p peer.Peer, k u.Key) error { - rs.delay.Wait() // before locking +type providerRecord struct { + Peer peer.Peer + Created time.Time +} +func (rs *s) Announce(p peer.Peer, k u.Key) error { rs.lock.Lock() defer rs.lock.Unlock() _, ok := rs.providers[k] if !ok { - rs.providers[k] = make(peer.Map) + rs.providers[k] = make(map[u.Key]providerRecord) + } + rs.providers[k][p.Key()] = providerRecord{ + Created: time.Now(), + Peer: p, } - rs.providers[k][p.Key()] = p return nil } func (rs *s) Providers(k u.Key) []peer.Peer { - rs.delay.Wait() // before locking + rs.delayConf.Query.Wait() // before locking rs.lock.RLock() defer rs.lock.RUnlock() var ret []peer.Peer - peerset, ok := rs.providers[k] + records, ok := rs.providers[k] if !ok { return ret } - for _, peer := range peerset { - ret = append(ret, peer) + for _, r := range records { + if time.Now().Sub(r.Created) > rs.delayConf.ValueVisibility.Get() { + ret = append(ret, r.Peer) + } } for i := range ret { -- GitLab