centralized_server.go 2.04 KB
Newer Older
Brian Tiger Chow's avatar
Brian Tiger Chow committed
1 2 3
package mockrouting

import (
4
	"context"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
5 6
	"math/rand"
	"sync"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
7
	"time"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
8

9
	"github.com/ipfs/go-ipfs/thirdparty/testutil"
10

Jeromy's avatar
Jeromy committed
11 12
	ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
	dssync "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore/sync"
13
	pstore "gx/ipfs/QmXZSd1qR5BxZkPyuwfT5jpqQFScZccoZvDneXsKzCNHWX/go-libp2p-peerstore"
14 15
	cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid"
	peer "gx/ipfs/QmdS9KpbDyPrieswibZhkod1oXqRwZJrUPzxCofAMWpFGq/go-libp2p-peer"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
16 17 18 19
)

// server is the mockrouting.Client's private interface to the routing server
type server interface {
20 21
	Announce(pstore.PeerInfo, *cid.Cid) error
	Providers(*cid.Cid) []pstore.PeerInfo
Brian Tiger Chow's avatar
Brian Tiger Chow committed
22 23 24 25 26 27

	Server
}

// s is an implementation of the private server interface
type s struct {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
28
	delayConf DelayConfig
Brian Tiger Chow's avatar
Brian Tiger Chow committed
29 30

	lock      sync.RWMutex
31
	providers map[string]map[peer.ID]providerRecord
Brian Tiger Chow's avatar
Brian Tiger Chow committed
32 33
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
34
type providerRecord struct {
Jeromy's avatar
Jeromy committed
35
	Peer    pstore.PeerInfo
Brian Tiger Chow's avatar
Brian Tiger Chow committed
36 37
	Created time.Time
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
38

39
func (rs *s) Announce(p pstore.PeerInfo, c *cid.Cid) error {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
40 41 42
	rs.lock.Lock()
	defer rs.lock.Unlock()

43 44
	k := c.KeyString()

Brian Tiger Chow's avatar
Brian Tiger Chow committed
45 46
	_, ok := rs.providers[k]
	if !ok {
47
		rs.providers[k] = make(map[peer.ID]providerRecord)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
48
	}
49
	rs.providers[k][p.ID] = providerRecord{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
50 51
		Created: time.Now(),
		Peer:    p,
Brian Tiger Chow's avatar
Brian Tiger Chow committed
52 53 54 55
	}
	return nil
}

56
func (rs *s) Providers(c *cid.Cid) []pstore.PeerInfo {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
57
	rs.delayConf.Query.Wait() // before locking
Brian Tiger Chow's avatar
Brian Tiger Chow committed
58 59 60

	rs.lock.RLock()
	defer rs.lock.RUnlock()
61
	k := c.KeyString()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
62

Jeromy's avatar
Jeromy committed
63
	var ret []pstore.PeerInfo
Brian Tiger Chow's avatar
Brian Tiger Chow committed
64
	records, ok := rs.providers[k]
Brian Tiger Chow's avatar
Brian Tiger Chow committed
65 66 67
	if !ok {
		return ret
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
68 69 70 71
	for _, r := range records {
		if time.Now().Sub(r.Created) > rs.delayConf.ValueVisibility.Get() {
			ret = append(ret, r.Peer)
		}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
72 73 74 75 76 77 78 79 80 81
	}

	for i := range ret {
		j := rand.Intn(i + 1)
		ret[i], ret[j] = ret[j], ret[i]
	}

	return ret
}

82
func (rs *s) Client(p testutil.Identity) Client {
Jeromy's avatar
Jeromy committed
83
	return rs.ClientWithDatastore(context.Background(), p, dssync.MutexWrap(ds.NewMapDatastore()))
Brian Tiger Chow's avatar
Brian Tiger Chow committed
84 85
}

86
func (rs *s) ClientWithDatastore(_ context.Context, p testutil.Identity, datastore ds.Datastore) Client {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
87 88
	return &client{
		peer:      p,
89
		datastore: datastore,
Brian Tiger Chow's avatar
Brian Tiger Chow committed
90 91 92
		server:    rs,
	}
}