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

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

8
	"github.com/ipfs/go-ipfs/thirdparty/testutil"
George Antoniadis's avatar
George Antoniadis committed
9 10 11
	ds "gx/ipfs/QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU/go-datastore"
	dssync "gx/ipfs/QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU/go-datastore/sync"
	key "gx/ipfs/Qmce4Y4zg3sYr7xKM5UueS67vhNni6EeWgCRnb7MbLJMew/go-key"
Jeromy's avatar
Jeromy committed
12

13
	peer "gx/ipfs/QmWXjJo15p4pzT7cayEwZi2sWgJqLnGDof6ZGMh9xBgU1p/go-libp2p-peer"
Jeromy's avatar
Jeromy committed
14
	pstore "gx/ipfs/QmYkwVGkwoPbMVQEbf6LonZg4SsCxGP3H7PBEtdNCNRyxD/go-libp2p-peerstore"
Jeromy's avatar
Jeromy committed
15
	context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
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 {
Jeromy's avatar
Jeromy committed
20 21
	Announce(pstore.PeerInfo, key.Key) error
	Providers(key.Key) []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[key.Key]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

Jeromy's avatar
Jeromy committed
39
func (rs *s) Announce(p pstore.PeerInfo, k key.Key) error {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
40 41 42 43 44
	rs.lock.Lock()
	defer rs.lock.Unlock()

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

Jeromy's avatar
Jeromy committed
54
func (rs *s) Providers(k key.Key) []pstore.PeerInfo {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
55
	rs.delayConf.Query.Wait() // before locking
Brian Tiger Chow's avatar
Brian Tiger Chow committed
56 57 58 59

	rs.lock.RLock()
	defer rs.lock.RUnlock()

Jeromy's avatar
Jeromy committed
60
	var ret []pstore.PeerInfo
Brian Tiger Chow's avatar
Brian Tiger Chow committed
61
	records, ok := rs.providers[k]
Brian Tiger Chow's avatar
Brian Tiger Chow committed
62 63 64
	if !ok {
		return ret
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
65 66 67 68
	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
69 70 71 72 73 74 75 76 77 78
	}

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

	return ret
}

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

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