Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

fix over-wait in WaitPub #53

Merged
merged 1 commit into from
Jan 14, 2019
Merged

fix over-wait in WaitPub #53

merged 1 commit into from
Jan 14, 2019

Conversation

Stebalien
Copy link
Member

@Stebalien Stebalien commented Jan 8, 2019

Before, WaitPub could wait forever if a value was published at the same time as the call to WaitPub.

This patch also avoids republishing the same value multiple times and allows setting an initial value without reaching in and modifying internal state.

fixes #38

@ghost ghost assigned Stebalien Jan 8, 2019
@ghost ghost added the status/in-progress In progress label Jan 8, 2019
@Stebalien
Copy link
Member Author

This could use a couple of good tests but it should fix #38.

Copy link
Contributor

@schomatis schomatis left a comment

Choose a reason for hiding this comment

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

In general this LGTM and it does fix #38 with some nice improvements, particularly it makes much more sense to have the last-published logic concentrated inside Run and not distributed throughout different methods.

Ideally (and I'm talking out of zero knowledge of the Go concurrent model) I would prefer to centralize as much logic as possible inside a single for/select pair (maybe offloading some logic to other methods) instead of having for-select-for-select (only for the sake of making the code easier to follow).

repub.go Outdated
return
case toPublish = <-rp.update:
if lastPublished.Equals(toPublish) {
break publishWaitLoop
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we not reset the timer in this case? Even if it's a repeated value my interpretation of the short timer is that it tracks activity (even dull activity), like a temporal locality, if someone updated the value recently there's a good chance it will update it again in the near future.

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case, it'll go back to the top which will reset the timer.

@@ -68,19 +67,23 @@ func (rp *Republisher) Close() error {
// channel. Multiple consecutive updates may extend the time period before
// the next publish occurs in order to more efficiently batch updates.
func (rp *Republisher) Update(c cid.Cid) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: update doc please.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

// concurrent publish and we can safely let that
// concurrent publish win.
}
case rp.update <- c:
}
}

// Run contains the core logic of the `Republisher`. It calls the user-defined
Copy link
Contributor

Choose a reason for hiding this comment

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

I think Run's logic has changed enough to deserve an update in its documentation.

// no more updates before it expires (restarted every time
// the `valueHasBeenUpdated` is signaled).
quick.Stop()
select {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit (and may even be wrong): Stop's documentation seems to be suggesting the simpler way:

// 	if !t.Stop() {
// 		<-t.C
// 	}

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately, that will deadlock if we loop without ever starting the timer. See: golang/go#18553.

Really, I just avoid that idiom so I never have to think about this. I've been bitten too many times.

repub.go Outdated
case <-quick:
case <-longer:
case valueHasBeenPublished = <-rp.immediatePublish:
case toPublish := <-rp.update:
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add more comments to this case please? I'm having trouble following the logic.

repub.go Outdated

case <-quick.C:
case <-longer.C:
case waiter := <-rp.immediatePublish:
Copy link
Contributor

Choose a reason for hiding this comment

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

So with this change WaitPub now does no longer trigger an immediate publish (immediate in the sense of not waiting for the timers) right? In that case could we rename the immediatePublish please?

Also, is this immediate publish feature currently expected by the users? Without clear documentation I guess it's hard to say, I'm appealing to your general knowledge of go-ipfs and IPNS in particular, the question being: is someone impacted by having to actually wait the short timeout every time it updates? (e.g., is someone doing many Updates/WaitPubs in a row to be impacted by it?)

Copy link
Member Author

Choose a reason for hiding this comment

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

🙄

I just wasn't thinking...

@Stebalien Stebalien force-pushed the fix/38 branch 2 times, most recently from 6b60060 to 30f0d7d Compare January 12, 2019 01:58
Before, WaitPub could wait forever if a value was published at the same time as
the call to WaitPub.

This patch also avoids republishing the same value multiple times and allows
setting an initial value without reaching in and modifying internal state.

fixes #38
@Stebalien
Copy link
Member Author

You were right, a single loop is much simpler. I ended up adding a second loop anyways to retry publishing (instead of just moving on) but this should be easier to understand.

Copy link
Contributor

@schomatis schomatis left a comment

Choose a reason for hiding this comment

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

Thanks for updating the documentation and the loop simplification, it's really nice. I definitely like the timer reorganization, it keeps everything moving even if we don't have anything to publish, avoiding potential deadlock situations with WaitPub.

@schomatis schomatis merged commit 996259a into master Jan 14, 2019
@ghost ghost removed the status/in-progress In progress label Jan 14, 2019
@schomatis schomatis deleted the fix/38 branch January 14, 2019 16:55
@magik6k
Copy link
Member

magik6k commented Jan 14, 2019

For some reason this PR seems to makes mfs fail to flush the root node when running commands locally (without the daemon), see ipfs/kubo#5925 (comment)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WaitPub may wait more than necessary
3 participants