Use bounded
rather than synchronous
in parJoin
#3027
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Copy/pasting some of my explanation from this Discord discussion:
The problem with
synchronous
is it basically eliminates parallel execution once you fill tomaxOpen
. As a reminder, even withsynchronous
, you will still havemaxOpen
chunks in memory since the streams have all run at least one step, it's just that these chunks are in memory in theflatMap
on theDeferred
, rather than directly in theChannel
. But the parallel execution thing is what I'm thinking right now. Imagine the downstream runs strictly slower than the upstreams. You will have the following stages in order:maxOpen
)In other words, due to
synchronous
,parJoin
is not actually parallel in a lot of cases! It is parallel resource consumption, but it is not parallel execution.bounded
fixes this because it allows downstream to consume up tomaxOpen
chunks at once, which in turn unblocks up tomaxOpen
of the upstreams. Withbounded(maxOpen)
, you get a sequence which looks more like the following:maxOpen
)maxOpen
chunksMaximum parallelism factor is
maxOpen + 1
(all upstreams + the downstream). Maximum memory footprint ismaxOpen * 2
. At steady-state, if all are proceeding at the same rate, the parallelism will equal the maximum parallelism. If the downstream is slower than the upstreams, then the parallelism will converge tomaxOpen
(whereas in thesynchronous
implementation, when the downstream is slow the parallelism converges to1
).