Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
p2p
go-p2p-swarm
Commits
988ab6cb
Commit
988ab6cb
authored
Jun 12, 2018
by
Łukasz Magiera
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
limiter: cleanup the code
parent
c1461238
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
59 additions
and
52 deletions
+59
-52
limiter.go
limiter.go
+57
-50
limiter_test.go
limiter_test.go
+2
-2
No files found.
limiter.go
View file @
988ab6cb
...
...
@@ -34,12 +34,13 @@ func (dj *dialJob) cancelled() bool {
}
type
dialLimiter
struct
{
rllock
sync
.
Mutex
lk
sync
.
Mutex
fdConsuming
int
fdLimit
int
waitingOnFd
[]
*
dialJob
dialFunc
func
(
context
.
Context
,
peer
.
ID
,
ma
.
Multiaddr
)
(
transport
.
Conn
,
error
)
dialFunc
dial
func
activePerPeer
map
[
peer
.
ID
]
int
perPeerLimit
int
...
...
@@ -62,26 +63,26 @@ func newDialLimiterWithParams(df dialfunc, fdLimit, perPeerLimit int) *dialLimit
}
}
func
(
dl
*
dialLimiter
)
finishedDial
(
dj
*
dialJob
)
{
dl
.
rllock
.
Lock
()
defer
dl
.
rllock
.
Unlock
()
if
addrutil
.
IsFDCostlyTransport
(
dj
.
addr
)
{
dl
.
fdConsuming
--
if
len
(
dl
.
waitingOnFd
)
>
0
{
next
:=
dl
.
waitingOnFd
[
0
]
dl
.
waitingOnFd
[
0
]
=
nil
// clear out memory
dl
.
waitingOnFd
=
dl
.
waitingOnFd
[
1
:
]
if
len
(
dl
.
waitingOnFd
)
==
0
{
dl
.
waitingOnFd
=
nil
// clear out memory
}
dl
.
fdConsuming
++
go
dl
.
executeDial
(
next
)
// freeFDToken frees FD token and if there are any schedules another waiting dialJob
// in it's place
func
(
dl
*
dialLimiter
)
freeFDToken
()
{
dl
.
fdConsuming
--
if
len
(
dl
.
waitingOnFd
)
>
0
{
next
:=
dl
.
waitingOnFd
[
0
]
dl
.
waitingOnFd
[
0
]
=
nil
// clear out memory
dl
.
waitingOnFd
=
dl
.
waitingOnFd
[
1
:
]
if
len
(
dl
.
waitingOnFd
)
==
0
{
dl
.
waitingOnFd
=
nil
// clear out memory
}
dl
.
fdConsuming
++
// we already have activePerPeer token at this point so we can just dial
go
dl
.
executeDial
(
next
)
}
}
func
(
dl
*
dialLimiter
)
freePeerToken
(
dj
*
dialJob
)
{
// release tokens in reverse order than we take them
dl
.
activePerPeer
[
dj
.
peer
]
--
if
dl
.
activePerPeer
[
dj
.
peer
]
==
0
{
...
...
@@ -91,45 +92,31 @@ func (dl *dialLimiter) finishedDial(dj *dialJob) {
waitlist
:=
dl
.
waitingOnPeerLimit
[
dj
.
peer
]
if
!
dj
.
success
&&
len
(
waitlist
)
>
0
{
next
:=
waitlist
[
0
]
if
len
(
waitlist
)
==
1
{
delete
(
dl
.
waitingOnPeerLimit
,
dj
.
peer
)
delete
(
dl
.
waitingOnPeerLimit
,
next
.
peer
)
}
else
{
waitlist
[
0
]
=
nil
// clear out memory
dl
.
waitingOnPeerLimit
[
dj
.
peer
]
=
waitlist
[
1
:
]
dl
.
waitingOnPeerLimit
[
next
.
peer
]
=
waitlist
[
1
:
]
}
dl
.
activePerPeer
[
dj
.
peer
]
++
// just kidding, we still want this token
if
addrutil
.
IsFDCostlyTransport
(
next
.
addr
)
{
if
dl
.
fdConsuming
>=
dl
.
fdLimit
{
dl
.
waitingOnFd
=
append
(
dl
.
waitingOnFd
,
next
)
return
}
// take token
dl
.
fdConsuming
++
}
dl
.
activePerPeer
[
next
.
peer
]
++
// just kidding, we still want this token
// can kick this off right here, dials in this list already
// have the other tokens needed
go
dl
.
executeDial
(
next
)
dl
.
addCheckFdLimit
(
next
)
}
}
// AddDialJob tries to take the needed tokens for starting the given dial job.
// If it acquires all needed tokens, it immediately starts the dial, otherwise
// it will put it on the waitlist for the requested token.
func
(
dl
*
dialLimiter
)
AddDialJob
(
dj
*
dialJob
)
{
dl
.
rllock
.
Lock
()
defer
dl
.
rllock
.
Unlock
()
func
(
dl
*
dialLimiter
)
finishedDial
(
dj
*
dialJob
)
{
dl
.
lk
.
Lock
()
defer
dl
.
lk
.
Unlock
()
if
dl
.
activePerPeer
[
dj
.
peer
]
>=
dl
.
perPeerLimit
{
wlist
:=
dl
.
waitingOnPeerLimit
[
dj
.
peer
]
dl
.
waitingOnPeerLimit
[
dj
.
peer
]
=
append
(
wlist
,
dj
)
return
if
addrutil
.
IsFDCostlyTransport
(
dj
.
addr
)
{
dl
.
freeFDToken
()
}
dl
.
activePerPeer
[
dj
.
peer
]
++
dl
.
freePeerToken
(
dj
)
}
func
(
dl
*
dialLimiter
)
addCheckFdLimit
(
dj
*
dialJob
)
{
if
addrutil
.
IsFDCostlyTransport
(
dj
.
addr
)
{
if
dl
.
fdConsuming
>=
dl
.
fdLimit
{
dl
.
waitingOnFd
=
append
(
dl
.
waitingOnFd
,
dj
)
...
...
@@ -140,15 +127,35 @@ func (dl *dialLimiter) AddDialJob(dj *dialJob) {
dl
.
fdConsuming
++
}
// take second needed token and start dial!
go
dl
.
executeDial
(
dj
)
}
func
(
dl
*
dialLimiter
)
addCheckPeerLimit
(
dj
*
dialJob
)
{
if
dl
.
activePerPeer
[
dj
.
peer
]
>=
dl
.
perPeerLimit
{
wlist
:=
dl
.
waitingOnPeerLimit
[
dj
.
peer
]
dl
.
waitingOnPeerLimit
[
dj
.
peer
]
=
append
(
wlist
,
dj
)
return
}
dl
.
activePerPeer
[
dj
.
peer
]
++
dl
.
addCheckFdLimit
(
dj
)
}
// AddDialJob tries to take the needed tokens for starting the given dial job.
// If it acquires all needed tokens, it immediately starts the dial, otherwise
// it will put it on the waitlist for the requested token.
func
(
dl
*
dialLimiter
)
AddDialJob
(
dj
*
dialJob
)
{
dl
.
lk
.
Lock
()
defer
dl
.
lk
.
Unlock
()
dl
.
addCheckPeerLimit
(
dj
)
}
func
(
dl
*
dialLimiter
)
clearAllPeerDials
(
p
peer
.
ID
)
{
dl
.
rlloc
k
.
Lock
()
defer
dl
.
rlloc
k
.
Unlock
()
dl
.
l
k
.
Lock
()
defer
dl
.
l
k
.
Unlock
()
delete
(
dl
.
waitingOnPeerLimit
,
p
)
// NB: the waitingOnFd list doesnt need to be cleaned out here, we will
// NB: the waitingOnFd list doesn
'
t need to be cleaned out here, we will
// remove them as we encounter them because they are 'cancelled' at this
// point
}
...
...
limiter_test.go
View file @
988ab6cb
...
...
@@ -378,9 +378,9 @@ func TestFDLimitUnderflow(t *testing.T) {
time
.
Sleep
(
time
.
Second
*
3
)
l
.
rlloc
k
.
Lock
()
l
.
l
k
.
Lock
()
fdConsuming
:=
l
.
fdConsuming
l
.
rlloc
k
.
Unlock
()
l
.
l
k
.
Unlock
()
if
fdConsuming
<
0
{
t
.
Fatalf
(
"l.fdConsuming < 0"
)
...
...
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