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

Enable switching DHT between client and server modes #469

Merged
merged 12 commits into from
Mar 6, 2020

Conversation

aschmahmann
Copy link
Contributor

This is needed to support libp2p peers that want to switch between client and server DHT modes while the peers are operational.

  1. Exposes a SetMode(DHTMode) that allows manually setting the mode
  2. Adds a utility function RoutabilityBasedModeSwitching(*dht) that will use the libp2p eventbus to automatically trigger mode switches (e.g. based on AutoNat emitting LocalRoutability events)

There are other ways we could expose this functionality such as:

  1. Adding a function option to the DHT instead of requiring RoutabilityBasedModeSwitching to be called on a DHT instance
    • Cannot do naively without refactoring since the DHT depends on the options package, so the options package cannot depend on the DHT
    • Could move the DHTMode to be declared outside of the dht package (e.g. options or a new one) and then define an interface with enough of the DHT functionality supported to make this work
  2. Add an option to the DHT for a function that returns a channel of DHTMode
    • Requires moving DHTMode to another package
    • Requires an extra goroutine to pull data off the eventbus and put it into a channel

All of these options could potentially run into issues if events get dropped off the eventbus, so following recommendations from the stabilize branch I've set the eventbus subscription buffer size to 256. Depending on the risk associated with dropping eventbus messages we may either want a way to define a stateful event channel (e.g. when a new event comes in throw away existing events and add the new one), or have some way of detecting dropped messages and then checking the relevant service.

dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht_test.go Show resolved Hide resolved
@aschmahmann aschmahmann self-assigned this Mar 3, 2020
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht_test.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht_net.go Outdated Show resolved Hide resolved
dht_net.go Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
dht.go Outdated Show resolved Hide resolved
@aschmahmann aschmahmann force-pushed the feat/mode-switching branch 2 times, most recently from 0930def to 0aa4675 Compare March 5, 2020 06:02
@Stebalien Stebalien force-pushed the cypress branch 2 times, most recently from 22b3963 to 5d313b1 Compare March 5, 2020 06:26
Copy link
Contributor Author

@aschmahmann aschmahmann left a comment

Choose a reason for hiding this comment

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

Next draft is up, let me know what you think so we can get this 🚢

dht.go Show resolved Hide resolved
dht.go Show resolved Hide resolved
dht_test.go Show resolved Hide resolved
dht_test.go Show resolved Hide resolved
@@ -31,7 +31,7 @@ func TestGetFailures(t *testing.T) {
host1 := bhost.New(swarmt.GenSwarm(t, ctx, swarmt.OptDisableReuseport))
host2 := bhost.New(swarmt.GenSwarm(t, ctx, swarmt.OptDisableReuseport))

d, err := New(ctx, host1, opts.DisableAutoRefresh())
d, err := New(ctx, host1, opts.DisableAutoRefresh(), opts.Mode(opts.ModeServer))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, so your tests break here too.

subscriber_notifee.go Show resolved Hide resolved
Comment on lines 45 to 47
&event.EvtLocalRoutabilityPublic{},
&event.EvtLocalRoutabilityPrivate{},
&event.EvtLocalRoutabilityUnknown{},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

subscriber_notifee.go Show resolved Hide resolved
Copy link
Contributor

@aarshkshah1992 aarshkshah1992 left a comment

Choose a reason for hiding this comment

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

@aschmahmann Great stuff ! :)

subscriber_notifee.go Show resolved Hide resolved
dht_test.go Show resolved Hide resolved
subscriber_notifee.go Show resolved Hide resolved
dht_test.go Show resolved Hide resolved
subscriber_notifee.go Outdated Show resolved Hide resolved
subscriber_notifee.go Show resolved Hide resolved
subscriber_notifee.go Outdated Show resolved Hide resolved
defer dht.plk.Unlock()
if dht.host.Network().Connectedness(e.Peer) != network.Connected {
return
}
Copy link
Member

Choose a reason for hiding this comment

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

Note: I believe both this check and this lock can go away once we switch to the new routing table logic. At that point, it's actually perfectly fine to add disconnected peers to our routing table.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aarshkshah1992 can you confirm, I haven't had time to look through the routing table PR yet.

Copy link
Member

Choose a reason for hiding this comment

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

I talked with him about this and I was wrong. We can make this possible with a small tweak to the routing table, but we'll handle that later.

(small tweak == get rid of live/dead states, just call a "checkPeer" function on all peers every tick)

subscriber_notifee.go Show resolved Hide resolved
case event.EvtPeerProtocolsUpdated:
handlePeerProtocolsUpdatedEvent(dht, evt)
case event.EvtLocalReachabilityChanged:
handleLocalReachabilityChangedEvent(dht, evt)
Copy link
Member

Choose a reason for hiding this comment

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

default: log error?

defer dht.plk.Unlock()
if dht.host.Network().Connectedness(e.Peer) != network.Connected {
return
}
Copy link
Member

Choose a reason for hiding this comment

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

I talked with him about this and I was wrong. We can make this possible with a small tweak to the routing table, but we'll handle that later.

(small tweak == get rid of live/dead states, just call a "checkPeer" function on all peers every tick)

@aschmahmann aschmahmann merged commit c24a52f into cypress Mar 6, 2020
@Stebalien Stebalien deleted the feat/mode-switching branch March 10, 2020 00:30
Stebalien pushed a commit that referenced this pull request Apr 3, 2020
* created Mode(ModeOpt) option for choosing between auto/client/server modes
* Auto mode internally switches the DHT between client and server modes based on the EvtLocalReachabilityChanged event emitted on the event bus (e.g. by AutoNAT)
* routing table management of peers that switch between client and server mode while we are connected to them (i.e. are in auto mode)
* removed Client(bool) option, becoming a DHT client is specified using Mode(ModeClient) instead
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.

5 participants