Commit 88a9bf04 authored by Brian Tiger Chow's avatar Brian Tiger Chow

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: default avatarBrian Tiger Chow <brian@perfmode.com>
parent 07e7f9a2
......@@ -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)
}
......
......@@ -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
}
......@@ -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()
}
}
......@@ -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 {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment