-
Notifications
You must be signed in to change notification settings - Fork 199
Fix permanent event batching for infinite buffers #325
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -122,6 +122,14 @@ defmodule GenStage.Buffer do | |
| take_count_or_until_permanent(counter, [], queue, buffer, infos) | ||
| end | ||
|
|
||
| defp take_count_or_until_permanent(0, temps, queue, buffer, infos) | ||
| when is_reference(infos) do | ||
| {queue, buffer, perms} = | ||
| take_permanents(queue, buffer, infos, []) | ||
|
|
||
| {:ok, {queue, buffer, infos}, 0, :lists.reverse(temps), :lists.reverse(perms)} | ||
| end | ||
|
|
||
| defp take_count_or_until_permanent(0, temps, queue, buffer, infos) do | ||
| {:ok, {queue, buffer, infos}, 0, :lists.reverse(temps), []} | ||
| end | ||
|
|
@@ -136,7 +144,10 @@ defmodule GenStage.Buffer do | |
|
|
||
| case value do | ||
| {^infos, perm} -> | ||
| {:ok, {queue, buffer - 1, infos}, counter, :lists.reverse(temps), [perm]} | ||
| {queue, buffer, perms} = | ||
| take_permanents(queue, buffer - 1, infos, [perm]) | ||
|
|
||
| {:ok, {queue, buffer, infos}, counter, :lists.reverse(temps), :lists.reverse(perms)} | ||
|
|
||
| temp -> | ||
| take_count_or_until_permanent(counter - 1, [temp | temps], queue, buffer - 1, infos) | ||
|
|
@@ -155,6 +166,17 @@ defmodule GenStage.Buffer do | |
| end | ||
| end | ||
|
|
||
| defp take_permanents(queue, buffer, infos, perms) do | ||
| case :queue.peek(queue) do | ||
| {:value, {^infos, perm}} -> | ||
| {{:value, _}, queue} = :queue.out(queue) | ||
| take_permanents(queue, buffer - 1, infos, [perm | perms]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to worry about buffer going eventually negative? Can we add a test or is it bound to the queue size anyway?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe it is bounded by the queue size, since each permanent stored in the infinite buffer increments the count and the helper only decrements it when another permanent entry is actually present in the queue. I also added an assertion that the buffer count reaches 0 when all entries are consumed. |
||
|
|
||
| _ -> | ||
| {queue, buffer, perms} | ||
| end | ||
| end | ||
|
|
||
| ## Wheel helpers | ||
|
|
||
| defp init_wheel(:infinity), do: make_ref() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the other clauses? Is this an issue:
When the last requested temporary event makes
counter - 1 == 0, recursion enters the zero-counter clause before examining the following permanent entries andtake_permanents/4is never called:If so, we need to add a test for it.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was an issue. I added a regression test for this case and updated the infinite-buffer path to handle permanents when the counter reaches zero.