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

DebouncedChan: When channel is firing continously, only fire once per period #222

Merged
merged 1 commit into from
Feb 22, 2024

Conversation

brandur
Copy link
Contributor

@brandur brandur commented Feb 22, 2024

This one's a follow up to #221. DebouncedChan previously had a bit of
a bug where if Call was being invoked continuously, it was firing more
often than expected: once for an initial Call, and then again when the
timer elapsed.

Here, we modify the implementation so that under a continuous fire
situation, DebouncedChan will fire once initially, and then once every
time the timer elapses at the end of each period. This reduces the
number of emits on C from 2N+1 to the more expected N+1 (the +1 being
the initial fire).

We accomplish this by entering a loop that waits on the timer when
receiving an initial Call, with the loop continuously resetting and
waiting on the timer after each time it fires, sending on C each time
the period elapses where a Call invocation came in. If a period
elapses without a new Call coming in, the timer stops, the loop
returns and DebouncedChan returns to its initial state.

// of +/-2 to allow the channel to be off by two cycles in either direction.
// By running at `-count 1000` or so I can usually reproduce an
// off-by-one-or-two cycle.
expectedNumSignal := int(math.Round(float64(testTime)/float64(cooldown))) + 1
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the key test change here: notice how we drop the *2 expected invocations.

@brandur brandur force-pushed the brandur-fire-only-once-per-period branch 2 times, most recently from af5b789 to 0afda9e Compare February 22, 2024 03:09
@brandur brandur requested a review from bgentry February 22, 2024 03:12
@brandur brandur force-pushed the brandur-fire-only-once-per-period branch from 0afda9e to a43a1d7 Compare February 22, 2024 14:27
Copy link
Contributor

@bgentry bgentry left a comment

Choose a reason for hiding this comment

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

Looks fantastic 🙌 :shipit:

@@ -79,25 +83,52 @@ func (d *DebouncedChan) nonBlockingSendOnC() {
}
}

func (d *DebouncedChan) waitForTimer() {
// Waits for the timer to be fired, and loops as long as Call invocations comes
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Waits for the timer to be fired, and loops as long as Call invocations comes
// Waits for the timer to be fired, and loops as long as Call invocations come

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, thanks. Fixed!

@bgentry
Copy link
Contributor

bgentry commented Feb 22, 2024

Oh, do you think this is changelog worthy? I would list it as a minor fix in there.

… period

This one's a follow up to #221. `DebouncedChan` previously had a bit of
a bug where if `Call` was being invoked continuously, it was firing more
often than expected: once for an initial `Call`, and then again when the
timer elapsed.

Here, we modify the implementation so that under a continuous fire
situation, `DebouncedChan` will fire once initially, and then once every
time the timer elapses at the end of each period. This reduces the
number of emits on `C` from 2N+1 to the more expected N+1 (the +1 being
the initial fire).

We accomplish this by entering a loop that waits on the timer when
receiving an initial `Call`, with the loop continuously resetting and
waiting on the timer after each time it fires, sending on `C` each time
the period elapses where a `Call` invocation came in. If a period
elapses without a new `Call` coming in, the timer stops, the loop
returns and `DebouncedChan` returns to its initial state.
@brandur brandur force-pushed the brandur-fire-only-once-per-period branch from a43a1d7 to d593ae1 Compare February 22, 2024 15:48
@brandur
Copy link
Contributor Author

brandur commented Feb 22, 2024

Oh, do you think this is changelog worthy? I would list it as a minor fix in there.

Yeah I was having a hard time deciding whether to mention it or not. Added an entry now.

@brandur
Copy link
Contributor Author

brandur commented Feb 22, 2024

Thanks!

@brandur brandur merged commit d3bdd56 into master Feb 22, 2024
9 of 10 checks passed
@brandur brandur deleted the brandur-fire-only-once-per-period branch February 22, 2024 15:54
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.

2 participants