Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mybee
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
mybee
Commits
17e187f0
Unverified
Commit
17e187f0
authored
May 25, 2021
by
Esad Akar
Committed by
GitHub
May 25, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: waitNext map as a type (#1863)
parent
ce1889d3
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
54 deletions
+150
-54
waitnext.go
pkg/topology/kademlia/internal/waitnext/waitnext.go
+79
-0
waitnext_test.go
pkg/topology/kademlia/internal/waitnext/waitnext_test.go
+54
-0
kademlia.go
pkg/topology/kademlia/kademlia.go
+17
-54
No files found.
pkg/topology/kademlia/internal/waitnext/waitnext.go
0 → 100644
View file @
17e187f0
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package metrics provides service for collecting various metrics about peers.
// It is intended to be used with the kademlia where the metrics are collected.
package
waitnext
import
(
"sync"
"time"
"github.com/ethersphere/bee/pkg/swarm"
)
type
next
struct
{
tryAfter
time
.
Time
failedAttempts
int
}
type
WaitNext
struct
{
next
map
[
string
]
*
next
sync
.
Mutex
}
func
New
()
*
WaitNext
{
return
&
WaitNext
{
next
:
make
(
map
[
string
]
*
next
),
}
}
func
(
r
*
WaitNext
)
Set
(
addr
swarm
.
Address
,
tryAfter
time
.
Time
,
attempts
int
)
{
r
.
Lock
()
defer
r
.
Unlock
()
r
.
next
[
addr
.
ByteString
()]
=
&
next
{
tryAfter
:
tryAfter
,
failedAttempts
:
attempts
}
}
func
(
r
*
WaitNext
)
SetTryAfter
(
addr
swarm
.
Address
,
tryAfter
time
.
Time
)
{
r
.
Lock
()
defer
r
.
Unlock
()
if
info
,
ok
:=
r
.
next
[
addr
.
ByteString
()];
ok
{
info
.
tryAfter
=
tryAfter
}
else
{
r
.
next
[
addr
.
ByteString
()]
=
&
next
{
tryAfter
:
tryAfter
}
}
}
func
(
r
*
WaitNext
)
Waiting
(
addr
swarm
.
Address
)
bool
{
r
.
Lock
()
defer
r
.
Unlock
()
info
,
ok
:=
r
.
next
[
addr
.
ByteString
()]
return
ok
&&
time
.
Now
()
.
Before
(
info
.
tryAfter
)
}
func
(
r
*
WaitNext
)
Attempts
(
addr
swarm
.
Address
)
int
{
r
.
Lock
()
defer
r
.
Unlock
()
if
info
,
ok
:=
r
.
next
[
addr
.
ByteString
()];
ok
{
return
info
.
failedAttempts
}
return
0
}
func
(
r
*
WaitNext
)
Remove
(
addr
swarm
.
Address
)
{
r
.
Lock
()
defer
r
.
Unlock
()
delete
(
r
.
next
,
addr
.
ByteString
())
}
pkg/topology/kademlia/internal/waitnext/waitnext_test.go
0 → 100644
View file @
17e187f0
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package metrics provides service for collecting various metrics about peers.
// It is intended to be used with the kademlia where the metrics are collected.
package
waitnext_test
import
(
"testing"
"time"
"github.com/ethersphere/bee/pkg/swarm/test"
"github.com/ethersphere/bee/pkg/topology/kademlia/internal/waitnext"
)
func
TestSet
(
t
*
testing
.
T
)
{
waitNext
:=
waitnext
.
New
()
addr
:=
test
.
RandomAddress
()
waitNext
.
Set
(
addr
,
time
.
Now
()
.
Add
(
time
.
Millisecond
*
10
),
2
)
if
!
waitNext
.
Waiting
(
addr
)
{
t
.
Fatal
(
"should be waiting"
)
}
time
.
Sleep
(
time
.
Millisecond
*
11
)
if
waitNext
.
Waiting
(
addr
)
{
t
.
Fatal
(
"should not be waiting"
)
}
if
attempts
:=
waitNext
.
Attempts
(
addr
);
attempts
!=
2
{
t
.
Fatalf
(
"want 2, got %d"
,
attempts
)
}
waitNext
.
SetTryAfter
(
addr
,
time
.
Now
()
.
Add
(
time
.
Millisecond
*
10
))
if
!
waitNext
.
Waiting
(
addr
)
{
t
.
Fatal
(
"should be waiting"
)
}
time
.
Sleep
(
time
.
Millisecond
*
11
)
if
waitNext
.
Waiting
(
addr
)
{
t
.
Fatal
(
"should not be waiting"
)
}
if
attempts
:=
waitNext
.
Attempts
(
addr
);
attempts
!=
2
{
t
.
Fatalf
(
"want 2, got %d"
,
attempts
)
}
}
pkg/topology/kademlia/kademlia.go
View file @
17e187f0
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
"github.com/ethersphere/bee/pkg/swarm"
"github.com/ethersphere/bee/pkg/swarm"
"github.com/ethersphere/bee/pkg/topology"
"github.com/ethersphere/bee/pkg/topology"
"github.com/ethersphere/bee/pkg/topology/kademlia/internal/metrics"
"github.com/ethersphere/bee/pkg/topology/kademlia/internal/metrics"
"github.com/ethersphere/bee/pkg/topology/kademlia/internal/waitnext"
"github.com/ethersphere/bee/pkg/topology/pslice"
"github.com/ethersphere/bee/pkg/topology/pslice"
ma
"github.com/multiformats/go-multiaddr"
ma
"github.com/multiformats/go-multiaddr"
)
)
...
@@ -82,8 +83,6 @@ type Kad struct {
...
@@ -82,8 +83,6 @@ type Kad struct {
radius
uint8
// storage area of responsibility
radius
uint8
// storage area of responsibility
depthMu
sync
.
RWMutex
// protect depth changes
depthMu
sync
.
RWMutex
// protect depth changes
manageC
chan
struct
{}
// trigger the manage forever loop to connect to new peers
manageC
chan
struct
{}
// trigger the manage forever loop to connect to new peers
waitNext
map
[
string
]
retryInfo
// sanction connections to a peer, key is overlay string and value is a retry information
waitNextMu
sync
.
Mutex
// guards waitNext map
peerSig
[]
chan
struct
{}
peerSig
[]
chan
struct
{}
peerSigMtx
sync
.
Mutex
peerSigMtx
sync
.
Mutex
logger
logging
.
Logger
// logger
logger
logging
.
Logger
// logger
...
@@ -93,11 +92,7 @@ type Kad struct {
...
@@ -93,11 +92,7 @@ type Kad struct {
quit
chan
struct
{}
// quit channel
quit
chan
struct
{}
// quit channel
done
chan
struct
{}
// signal that `manage` has quit
done
chan
struct
{}
// signal that `manage` has quit
wg
sync
.
WaitGroup
wg
sync
.
WaitGroup
}
waitNext
*
waitnext
.
WaitNext
type
retryInfo
struct
{
tryAfter
time
.
Time
failedAttempts
int
}
}
// New returns a new Kademlia.
// New returns a new Kademlia.
...
@@ -133,7 +128,7 @@ func New(
...
@@ -133,7 +128,7 @@ func New(
knownPeers
:
pslice
.
New
(
int
(
swarm
.
MaxBins
)),
knownPeers
:
pslice
.
New
(
int
(
swarm
.
MaxBins
)),
bootnodes
:
o
.
Bootnodes
,
bootnodes
:
o
.
Bootnodes
,
manageC
:
make
(
chan
struct
{},
1
),
manageC
:
make
(
chan
struct
{},
1
),
waitNext
:
make
(
map
[
string
]
retryInfo
),
waitNext
:
waitnext
.
New
(
),
logger
:
logger
,
logger
:
logger
,
standalone
:
o
.
StandaloneMode
,
standalone
:
o
.
StandaloneMode
,
bootnode
:
o
.
BootnodeMode
,
bootnode
:
o
.
BootnodeMode
,
...
@@ -237,10 +232,7 @@ type peerConnInfo struct {
...
@@ -237,10 +232,7 @@ type peerConnInfo struct {
// connectBalanced attempts to connect to the balanced peers first.
// connectBalanced attempts to connect to the balanced peers first.
func
(
k
*
Kad
)
connectBalanced
(
wg
*
sync
.
WaitGroup
,
peerConnChan
chan
<-
*
peerConnInfo
)
{
func
(
k
*
Kad
)
connectBalanced
(
wg
*
sync
.
WaitGroup
,
peerConnChan
chan
<-
*
peerConnInfo
)
{
skipPeers
:=
func
(
peer
swarm
.
Address
)
bool
{
skipPeers
:=
func
(
peer
swarm
.
Address
)
bool
{
k
.
waitNextMu
.
Lock
()
return
k
.
waitNext
.
Waiting
(
peer
)
defer
k
.
waitNextMu
.
Unlock
()
next
,
ok
:=
k
.
waitNext
[
peer
.
ByteString
()]
return
ok
&&
time
.
Now
()
.
Before
(
next
.
tryAfter
)
}
}
for
i
:=
range
k
.
commonBinPrefixes
{
for
i
:=
range
k
.
commonBinPrefixes
{
...
@@ -305,12 +297,9 @@ func (k *Kad) connectNeighbours(wg *sync.WaitGroup, peerConnChan chan<- *peerCon
...
@@ -305,12 +297,9 @@ func (k *Kad) connectNeighbours(wg *sync.WaitGroup, peerConnChan chan<- *peerCon
return
false
,
false
,
nil
return
false
,
false
,
nil
}
}
k
.
waitNextMu
.
Lock
()
if
k
.
waitNext
.
Waiting
(
addr
)
{
if
next
,
ok
:=
k
.
waitNext
[
addr
.
ByteString
()];
ok
&&
time
.
Now
()
.
Before
(
next
.
tryAfter
)
{
k
.
waitNextMu
.
Unlock
()
return
false
,
false
,
nil
return
false
,
false
,
nil
}
}
k
.
waitNextMu
.
Unlock
()
if
saturated
,
_
:=
k
.
saturationFunc
(
po
,
k
.
knownPeers
,
k
.
connectedPeers
);
saturated
{
if
saturated
,
_
:=
k
.
saturationFunc
(
po
,
k
.
knownPeers
,
k
.
connectedPeers
);
saturated
{
return
false
,
true
,
nil
// Bin is saturated, skip to next bin.
return
false
,
true
,
nil
// Bin is saturated, skip to next bin.
...
@@ -349,9 +338,7 @@ func (k *Kad) connectionAttemptsHandler(ctx context.Context, wg *sync.WaitGroup,
...
@@ -349,9 +338,7 @@ func (k *Kad) connectionAttemptsHandler(ctx context.Context, wg *sync.WaitGroup,
}
}
remove
:=
func
(
peer
*
peerConnInfo
)
{
remove
:=
func
(
peer
*
peerConnInfo
)
{
k
.
waitNextMu
.
Lock
()
k
.
waitNext
.
Remove
(
peer
.
addr
)
delete
(
k
.
waitNext
,
peer
.
addr
.
ByteString
())
k
.
waitNextMu
.
Unlock
()
k
.
knownPeers
.
Remove
(
peer
.
addr
,
peer
.
po
)
k
.
knownPeers
.
Remove
(
peer
.
addr
,
peer
.
po
)
if
err
:=
k
.
addressBook
.
Remove
(
peer
.
addr
);
err
!=
nil
{
if
err
:=
k
.
addressBook
.
Remove
(
peer
.
addr
);
err
!=
nil
{
k
.
logger
.
Debugf
(
"kademlia: could not remove peer %q from addressbook"
,
peer
.
addr
)
k
.
logger
.
Debugf
(
"kademlia: could not remove peer %q from addressbook"
,
peer
.
addr
)
...
@@ -373,9 +360,7 @@ func (k *Kad) connectionAttemptsHandler(ctx context.Context, wg *sync.WaitGroup,
...
@@ -373,9 +360,7 @@ func (k *Kad) connectionAttemptsHandler(ctx context.Context, wg *sync.WaitGroup,
return
return
}
}
k
.
waitNextMu
.
Lock
()
k
.
waitNext
.
Set
(
peer
.
addr
,
time
.
Now
()
.
Add
(
shortRetry
),
0
)
k
.
waitNext
[
peer
.
addr
.
ByteString
()]
=
retryInfo
{
tryAfter
:
time
.
Now
()
.
Add
(
shortRetry
)}
k
.
waitNextMu
.
Unlock
()
k
.
connectedPeers
.
Add
(
peer
.
addr
,
peer
.
po
)
k
.
connectedPeers
.
Add
(
peer
.
addr
,
peer
.
po
)
...
@@ -410,15 +395,10 @@ func (k *Kad) connectionAttemptsHandler(ctx context.Context, wg *sync.WaitGroup,
...
@@ -410,15 +395,10 @@ func (k *Kad) connectionAttemptsHandler(ctx context.Context, wg *sync.WaitGroup,
case
peer
:=
<-
peerConnChan
:
case
peer
:=
<-
peerConnChan
:
addr
:=
peer
.
addr
.
String
()
addr
:=
peer
.
addr
.
String
()
// Check if the peer was penalized.
if
k
.
waitNext
.
Waiting
(
peer
.
addr
)
{
k
.
waitNextMu
.
Lock
()
next
,
ok
:=
k
.
waitNext
[
peer
.
addr
.
ByteString
()]
if
ok
&&
time
.
Now
()
.
Before
(
next
.
tryAfter
)
{
k
.
waitNextMu
.
Unlock
()
wg
.
Done
()
wg
.
Done
()
continue
continue
}
}
k
.
waitNextMu
.
Unlock
()
inProgressMu
.
Lock
()
inProgressMu
.
Lock
()
if
!
inProgress
[
addr
]
{
if
!
inProgress
[
addr
]
{
...
@@ -679,12 +659,8 @@ func (k *Kad) connect(ctx context.Context, peer swarm.Address, ma ma.Multiaddr)
...
@@ -679,12 +659,8 @@ func (k *Kad) connect(ctx context.Context, peer swarm.Address, ma ma.Multiaddr)
if
errors
.
As
(
err
,
&
e
)
{
if
errors
.
As
(
err
,
&
e
)
{
retryTime
=
e
.
TryAfter
()
retryTime
=
e
.
TryAfter
()
}
else
{
}
else
{
k
.
waitNextMu
.
Lock
()
failedAttempts
=
k
.
waitNext
.
Attempts
(
peer
)
if
info
,
ok
:=
k
.
waitNext
[
peer
.
ByteString
()];
ok
{
failedAttempts
=
info
.
failedAttempts
}
failedAttempts
++
failedAttempts
++
k
.
waitNextMu
.
Unlock
()
}
}
if
err
:=
k
.
collector
.
Record
(
peer
,
metrics
.
IncSessionConnectionRetry
());
err
!=
nil
{
if
err
:=
k
.
collector
.
Record
(
peer
,
metrics
.
IncSessionConnectionRetry
());
err
!=
nil
{
...
@@ -694,21 +670,16 @@ func (k *Kad) connect(ctx context.Context, peer swarm.Address, ma ma.Multiaddr)
...
@@ -694,21 +670,16 @@ func (k *Kad) connect(ctx context.Context, peer swarm.Address, ma ma.Multiaddr)
if
err
:=
k
.
collector
.
Inspect
(
peer
,
func
(
ss
*
metrics
.
Snapshot
)
{
if
err
:=
k
.
collector
.
Inspect
(
peer
,
func
(
ss
*
metrics
.
Snapshot
)
{
quickPrune
:=
ss
==
nil
||
ss
.
HasAtMaxOneConnectionAttempt
()
quickPrune
:=
ss
==
nil
||
ss
.
HasAtMaxOneConnectionAttempt
()
k
.
waitNextMu
.
Lock
()
if
(
k
.
connectedPeers
.
Length
()
>
0
&&
quickPrune
)
||
failedAttempts
>
maxConnAttempts
{
if
(
k
.
connectedPeers
.
Length
()
>
0
&&
quickPrune
)
||
failedAttempts
>
maxConnAttempts
{
delete
(
k
.
waitNext
,
peer
.
ByteString
()
)
k
.
waitNext
.
Remove
(
peer
)
k
.
knownPeers
.
Remove
(
peer
,
swarm
.
Proximity
(
k
.
base
.
Bytes
(),
peer
.
Bytes
()))
k
.
knownPeers
.
Remove
(
peer
,
swarm
.
Proximity
(
k
.
base
.
Bytes
(),
peer
.
Bytes
()))
if
err
:=
k
.
addressBook
.
Remove
(
peer
);
err
!=
nil
{
if
err
:=
k
.
addressBook
.
Remove
(
peer
);
err
!=
nil
{
k
.
logger
.
Debugf
(
"could not remove peer from addressbook: %q"
,
peer
)
k
.
logger
.
Debugf
(
"could not remove peer from addressbook: %q"
,
peer
)
}
}
k
.
logger
.
Debugf
(
"kademlia pruned peer from address book %q"
,
peer
)
k
.
logger
.
Debugf
(
"kademlia pruned peer from address book %q"
,
peer
)
}
else
{
}
else
{
k
.
waitNext
[
peer
.
ByteString
()]
=
retryInfo
{
k
.
waitNext
.
Set
(
peer
,
retryTime
,
failedAttempts
)
tryAfter
:
retryTime
,
failedAttempts
:
failedAttempts
,
}
}
}
k
.
waitNextMu
.
Unlock
()
});
err
!=
nil
{
});
err
!=
nil
{
k
.
logger
.
Debugf
(
"kademlia: connect: unable to inspect snapshot for %q: %v"
,
peer
,
err
)
k
.
logger
.
Debugf
(
"kademlia: connect: unable to inspect snapshot for %q: %v"
,
peer
,
err
)
}
}
...
@@ -838,9 +809,7 @@ func (k *Kad) connected(ctx context.Context, addr swarm.Address) error {
...
@@ -838,9 +809,7 @@ func (k *Kad) connected(ctx context.Context, addr swarm.Address) error {
k
.
logger
.
Debugf
(
"kademlia: unable to record login inbound metrics for %q: %v"
,
addr
,
err
)
k
.
logger
.
Debugf
(
"kademlia: unable to record login inbound metrics for %q: %v"
,
addr
,
err
)
}
}
k
.
waitNextMu
.
Lock
()
k
.
waitNext
.
Remove
(
addr
)
delete
(
k
.
waitNext
,
addr
.
ByteString
())
k
.
waitNextMu
.
Unlock
()
k
.
depthMu
.
Lock
()
k
.
depthMu
.
Lock
()
k
.
depth
=
recalcDepth
(
k
.
connectedPeers
,
k
.
radius
)
k
.
depth
=
recalcDepth
(
k
.
connectedPeers
,
k
.
radius
)
...
@@ -859,13 +828,7 @@ func (k *Kad) Disconnected(peer p2p.Peer) {
...
@@ -859,13 +828,7 @@ func (k *Kad) Disconnected(peer p2p.Peer) {
po
:=
swarm
.
Proximity
(
k
.
base
.
Bytes
(),
peer
.
Address
.
Bytes
())
po
:=
swarm
.
Proximity
(
k
.
base
.
Bytes
(),
peer
.
Address
.
Bytes
())
k
.
connectedPeers
.
Remove
(
peer
.
Address
,
po
)
k
.
connectedPeers
.
Remove
(
peer
.
Address
,
po
)
k
.
waitNextMu
.
Lock
()
k
.
waitNext
.
SetTryAfter
(
peer
.
Address
,
time
.
Now
()
.
Add
(
timeToRetry
))
newInfo
:=
retryInfo
{
tryAfter
:
time
.
Now
()
.
Add
(
timeToRetry
),
failedAttempts
:
0
}
if
info
,
ok
:=
k
.
waitNext
[
peer
.
Address
.
ByteString
()];
ok
{
newInfo
.
failedAttempts
=
info
.
failedAttempts
}
k
.
waitNext
[
peer
.
Address
.
ByteString
()]
=
newInfo
k
.
waitNextMu
.
Unlock
()
if
err
:=
k
.
collector
.
Record
(
if
err
:=
k
.
collector
.
Record
(
peer
.
Address
,
peer
.
Address
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment