fix races in testnet
ConnectTo can be called concurrently from within bitswap. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>
Steven Allen committed
Dec 15, 2017 at 13:41 UTC
a77e0e471380252653df2bbeeff8e895fc030e4f
1 file changed
+21
-2
exchange/bitswap/testnet/virtual.go
+21
-2
@@ -3,6 +3,7 @@ package bitswap
3
import (
4
"context"
5
"errors"
6
+ "sync"
7
8
bsmsg "github.com/ipfs/go-ipfs/exchange/bitswap/message"
9
bsnet "github.com/ipfs/go-ipfs/exchange/bitswap/network"
@@ -29,6 +30,7 @@ func VirtualNetwork(rs mockrouting.Server, d delay.D) Network {
30
}
31
32
type network struct {
33
+ mu sync.Mutex
34
clients map[peer.ID]bsnet.Receiver
35
routingserver mockrouting.Server
36
delay delay.D
@@ -36,6 +38,9 @@ type network struct {
38
}
39
40
func (n *network) Adapter(p testutil.Identity) bsnet.BitSwapNetwork {
41
+ n.mu.Lock()
42
+ defer n.mu.Unlock()
43
+
44
client := &networkClient{
45
local: p.ID(),
46
network: n,
@@ -46,6 +51,9 @@ func (n *network) Adapter(p testutil.Identity) bsnet.BitSwapNetwork {
51
}
52
53
func (n *network) HasPeer(p peer.ID) bool {
54
+ n.mu.Lock()
55
+ defer n.mu.Unlock()
56
+
57
_, found := n.clients[p]
58
return found
59
}
@@ -58,6 +66,9 @@ func (n *network) SendMessage(
66
to peer.ID,
67
message bsmsg.BitSwapMessage) error {
68
69
+ n.mu.Lock()
70
+ defer n.mu.Unlock()
71
+
72
receiver, ok := n.clients[to]
73
if !ok {
74
return errors.New("Cannot locate peer on network")
@@ -161,18 +172,26 @@ func (nc *networkClient) SetDelegate(r bsnet.Receiver) {
172
}
173
174
func (nc *networkClient) ConnectTo(_ context.Context, p peer.ID) error {
164
- if !nc.network.HasPeer(p) {
175
+ nc.network.mu.Lock()
176
+
177
+ otherClient, ok := nc.network.clients[p]
178
+ if !ok {
179
+ nc.network.mu.Unlock()
180
return errors.New("no such peer in network")
181
}
182
+
183
tag := tagForPeers(nc.local, p)
184
if _, ok := nc.network.conns[tag]; ok {
185
+ nc.network.mu.Unlock()
186
log.Warning("ALREADY CONNECTED TO PEER (is this a reconnect? test lib needs fixing)")
187
return nil
188
}
189
nc.network.conns[tag] = struct{}{}
190
+ nc.network.mu.Unlock()
191
+
192
// TODO: add handling for disconnects
193
175
- nc.network.clients[p].PeerConnected(nc.local)
194
+ otherClient.PeerConnected(nc.local)
195
nc.Receiver.PeerConnected(p)
196
return nil
197
}