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

feat: refresh and wait #418

Merged
merged 2 commits into from
Dec 10, 2019
Merged

feat: refresh and wait #418

merged 2 commits into from
Dec 10, 2019

Conversation

Stebalien
Copy link
Member

We'd like to be able to refresh then wait for the refresh to finish in the testground DHT tests. That way, we can:

  1. Start and disable auto refresh.
  2. Bootstrap.
  3. Refresh a couple of times till we're stable.
  4. Wait to stop refreshing.
  5. Disconnect from and forget about all peers not in our routing tables.
  6. Run the actual tests without interference from the bootstrapping logic.

We'd like to be able to refresh then _wait_ for the refresh to finish in the testground DHT tests. That way, we can:

1. Start and disable _auto_ refresh.
2. Bootstrap.
3. Refresh a couple of times till we're stable.
4. Wait to _stop_ refreshing.
5. Disconnect from and forget about all peers _not_ in our routing tables.
6. Run the actual tests without interference from the bootstrapping logic.
Copy link
Contributor

@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.

well, it seems like a reasonable thing to do.

collectWaiting:
for {
select {
case res := <-dht.triggerRtRefresh:
Copy link
Contributor

Choose a reason for hiding this comment

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

@Stebalien

Is this second select here to handle the case where multiple callers might ask for a refresh "simultaneously" ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. I'll document that.

@@ -70,7 +70,7 @@ type IpfsDHT struct {
autoRefresh bool
rtRefreshQueryTimeout time.Duration
rtRefreshPeriod time.Duration
triggerRtRefresh chan struct{}
triggerRtRefresh chan chan<- error
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be just chan error?

@@ -167,7 +167,7 @@ func makeDHT(ctx context.Context, h host.Host, dstore ds.Batching, protocols []p
routingTable: rt,
protocols: protocols,
bucketSize: bucketSize,
triggerRtRefresh: make(chan struct{}),
triggerRtRefresh: make(chan chan<- error),
Copy link
Contributor

Choose a reason for hiding this comment

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

here too.

Copy link
Member Author

Choose a reason for hiding this comment

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

This one is slightly stricter.

@Stebalien
Copy link
Member Author

So, it turns out I don't absolutely need this unless we're also trying to test our bootstrapping logic (as I can just connect to all peers and call it a day).

Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

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

I think there's a more elegant API possible that does not pollute the namespace.

dht_bootstrap.go Outdated
@@ -148,7 +183,25 @@ func (dht *IpfsDHT) Bootstrap(_ context.Context) error {
// RefreshRoutingTable tells the DHT to refresh it's routing tables.
func (dht *IpfsDHT) RefreshRoutingTable() {
Copy link
Member

Choose a reason for hiding this comment

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

A simpler API would be to make RefreshRoutingTable() always return the channel making it non-buffered, and in the send to channel above, skip and close the channel if no one's receiving (select + default branch). Such an API change wouldn't be breaking.

Copy link
Member Author

Choose a reason for hiding this comment

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

SGTM. However:

  • It's technically breaking but only if someone defined an interface for this.
  • We have to write to the channel even if nobody's listening. Otherwise, we could return before the caller starts listening.

}
err := dht.doRefresh(ctx)
for _, w := range waiting {
w <- err
Copy link
Member

Choose a reason for hiding this comment

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

Close the channel?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not necessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

(well, if we're returning a channel, we should probably close it)

Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

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

This interface looks better to me!

@Stebalien Stebalien merged commit 6028925 into master Dec 10, 2019
@Stebalien Stebalien deleted the feat/refresh-and-wait branch December 10, 2019 17:04
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.

4 participants