Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 see how this is useful.
However, there is a catch: when we discover a new peer, we'll try to add it to the active set. Which may cause already-active peers to get demoted.
This is problematic when the disco stream is not coming from a static (bounded) set of bootstrap nodes, but for example from some periodic (m)DNS query, or some datasource which remembers a list of seen peers which is larger than the active set: the active set will constantly get replaced, causing a lot of churn. It will also converge the node to only be connected to the peers which are discovered via this stream, not the membership shuffle.
I haven't been able to come up with a good solution to this, but now that you're raising it: maybe the
disco
future could just go into a pending state while the membership active count (available throughstate.membership.view_stats().0
) is equal tonet::protocol::membership::Params::max_active
(not currently available to this function)? When it wakes up, and the count is smaller, it could popmax_active - active
from the stream and try to connect to those concurrently.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.
To elaborate on why this is bad: specifically mDNS could yield many peers on the local network, so we'd converge to only be connected to the local network. Which is clearly not what we want.
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.
Would it make sense then to handle the connection (
io::connection::connect()
) concurrently but the membership sequentially? In this case unreachable peers would not block membership rpc with other peers.The motivation for this PR is seed node selection in Upstream. Concretely, we just want to tell link to connect to a set of nodes. As an alternative to what I described above we could also provide a better API to achieve the Upstream use case. We could have a function that tells the local peer to connect to another remote node or we could change the discovery stream to
impl Stream<Item = Vec<PeerId, Vec<SocketAddr>>>
. (I’d prefer the former).