Skip to content
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

Add the ability to handle newly subscribed peers #190

Merged
merged 12 commits into from
Aug 7, 2019

Conversation

aschmahmann
Copy link
Contributor

Per conversations with @vyzo @raulk and @Stebalien we are refactoring the content of #171 which does 2 things.

  1. Gives developers control over what messages are broadcast
  2. Gives developers an "OnJoin" method that can specify an action to do when first connecting to a peer (e.g. send a specific message, utilize an external protocol, etc.)

Instead of doing this by making routers extensible, we will be leaving router extensibility for a later date and solve the issues above by:

  1. Using stateful validators + application layer publishing to effectively control which messages are broadcast. This can happen outside of the go-libp2p-pubsub package.
  2. Adding a mechanism for PubSub to expose when it connects to a new peer

This PR deals with the latter.

Copy link
Collaborator

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. Shouldn't we also notify when peers leave the topic however?

subscription.go Outdated Show resolved Hide resolved
@vyzo
Copy link
Collaborator

vyzo commented Jun 8, 2019

An issue here is that if we subscribe after peers have been discovered, there will be no notifications.
I think we might want to emit notifications for all known peers when we first subscribe.

@aschmahmann
Copy link
Contributor Author

While you could already get the existing peers with the FindPeers command, I think you're right that this would likely be useful for many developers. I'll likely just make the buffered channel large enough to fill with the initial peers and fill it up on initialization.

@aschmahmann
Copy link
Contributor Author

aschmahmann commented Jun 11, 2019

This looks good. Shouldn't we also notify when peers leave the topic however?

@vyzo That's fine by me. Any thoughts on how important receiving all the leave messages is? In particular, while joins might be slow enough that concurrent joins will not get dropped due to channel buffer overflow disconnecting from the internet might instead lead to mass connectivity dropping and therefore some missed NextPeerLeave events.

Also, wanted to confirm that blacklisting based disconnects should count towards Leave events also.

…re we subscribe.

Added a Subscription Leave event
Copy link
Collaborator

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a race to read join and leave notifications, as they are emitted in different channels.
I think we need a single channel for both notifications and use a struct with a field that specifies the notification type.

pubsub.go Outdated Show resolved Hide resolved
pubsub.go Outdated Show resolved Hide resolved
pubsub.go Outdated Show resolved Hide resolved
subscription.go Outdated Show resolved Hide resolved
Combined Join and Leave events into a single API with a struct that specifies whether the event is a Join or a Leave.
Copy link
Collaborator

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is looking good, just a few minor points.

pubsub.go Outdated Show resolved Hide resolved
pubsub.go Outdated Show resolved Hide resolved
pubsub.go Outdated Show resolved Hide resolved
subscription.go Outdated Show resolved Hide resolved
subscription.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only thing remaining to fix is the enum, other than that it looks good.

@aschmahmann aschmahmann mentioned this pull request Jul 22, 2019
subscription.go Outdated Show resolved Hide resolved
@aschmahmann
Copy link
Contributor Author

Latest idea for how to do this:

We effectively want an infinite length buffer so that no Joins/Leaves are lost. However, we can be slightly efficient by ignoring when the same peer Joins and Leaves before we even ask for a notification.

Strategy:
Have a channel that receives updates, if the channel is full empty it into the buffer which is a map protected by a mutex.
When asked for an update we pull from the buffer if it's not empty, otherwise we pull from the channel.

There are some side points around how to get this right and look clean that I could definitely use some review on.

@Stebalien
Copy link
Member

Have a channel that receives updates, if the channel is full empty it into the buffer which is a map protected by a mutex.
When asked for an update we pull from the buffer if it's not empty, otherwise we pull from the channel.

Maybe? I'm concerned about races reading the channel. Someone needs to drain the channel and we can't have both the subscriber and pubsub do this (or risk out of order events).

If we want to go with this approach, we could just put everything into the map up front (and use a channel for signaling).

subscription.go Outdated
}

select {
case evt, ok := <-sub.peerEvtCh:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is racy. We could be in the middle of draining this queue into the map and read an leave event before the join (now in the map).

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sorry, we missed a case)

subscription.go Outdated Show resolved Hide resolved
subscription.go Outdated Show resolved Hide resolved
…acklog into eventLog. removed test that was no longer useful.
case sub.evtLogCh <- struct{}{}:
default:
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Stebalien we thinking this works? I should only need to push a signal if there are events in the log right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Copy link
Collaborator

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright, let's merge this.

@vyzo vyzo merged commit 9f04364 into libp2p:master Aug 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants