-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Periodically schedule identify push if the address set has changed #597
Conversation
ci failed with a data race... |
insanity... |
I added a delay in the background task, but maybe we should have an explicit Start method that gets called by the constructor instead. |
Now we get this failure:
I'll gate this test. |
It's already gated, so I reduced the peer count further. |
Let's do an explicit start. |
Ok, will do. |
Added |
rebased on master. |
summoning @Stebalien |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, forgot about this halfway through my review. The only real issue is the permanent stall with a misbehaving peer.
p2p/host/basic/basic_host.go
Outdated
return false | ||
} | ||
|
||
// this is O(n*m), might be worth using a map to turn into O(n+m) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably is as some peers end up with a bunch of addresses. Alternatively, we could sort both lists.
(but we can probably fix that later if it shows up in profiles)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll fix it now, I don't like having perf bombs waiting to go off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented the map in b17ba31
p2p/protocol/identify/id.go
Outdated
s, err := ids.Host.NewStream(ctx, p, IDPush) | ||
if err != nil { | ||
log.Debugf("error opening push stream: %s", err.Error()) | ||
log.Debugf("error opening push stream to %s: %s", p, err.Error()) | ||
return | ||
} | ||
|
||
ids.requestHandler(s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Not a bug in this PR but we should probably:
- Do this in a goroutine.
- Reset the stream if the context expires.
At the moment, we can hang the entire push if a single peer stalls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this is now an issue because we're blocking everything else (which we weren't doing before).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can move the context back into the goroutine and remove the wait group, so that we don't stall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the only reason I did this dance with the wait group was my desire to reuse the context instead of creating one for each peer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you want the ids.requestHandler
call in a goroutine, so that we don't stall; much better than exploding the contexts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also note we are not blocking anything, there is a supervisory goroutine waiting for the WaitGroup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might simply get away with setting a Deadline
in the stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5503cd7
I moved the ids.requestHandler
into a goroutine and added a wait for the context cancellation to reset the stream if the handler doesn't complete by then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also note we are not blocking anything, there is a supervisory goroutine waiting for the WaitGroup.
Ah, got it. But better to reset the stream anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's not build up goroutines if we have a stuck peer.
Note: multiple contexts is actually pretty cheap. |
p2p/host/basic/basic_host.go
Outdated
return false | ||
} | ||
|
||
bmap := make(map[string]struct{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: we could preallocate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, will pass a length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
rebased on master for merging. |
Adds a background task to basic host, that periodically schedules an identify push if the address set has changed.