Skip to content

Conversation

DaveCTurner
Copy link
Contributor

Today a CountDownActionListener which wraps a bare Runnable collects all the exceptions it receives only to drop them when finally completing the delegate action. Moreover callers must declare up-front the number of times the listener will be completed, which means they must put extra effort into computing this number ahead of time and/or supply an overestimate and then make up the difference with additional artificial completions.

This commit introduces RefCountingRunnable which allows callers to acquire and release references as needed, executing the delegate Runnable once all references are released. It also refactors all the relevant call sites to use this new utility.

Today a `CountDownActionListener` which wraps a bare `Runnable` collects
all the exceptions it receives only to drop them when finally completing
the delegate action. Moreover callers must declare up-front the number
of times the listener will be completed, which means they must put extra
effort into computing this number ahead of time and/or supply an
overestimate and then make up the difference with additional artificial
completions.

This commit introduces `RefCountingRunnable` which allows callers to
acquire and release references as needed, executing the delegate
`Runnable` once all references are released. It also refactors all the
relevant call sites to use this new utility.
@DaveCTurner DaveCTurner added :Core/Infra/Core Core issues without another label >refactoring v8.7.0 labels Jan 3, 2023
@DaveCTurner DaveCTurner requested a review from joegallo January 3, 2023 08:42
@elasticsearchmachine elasticsearchmachine added the Team:Core/Infra Meta label for core/infra team label Jan 3, 2023
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@DaveCTurner
Copy link
Contributor Author

DaveCTurner commented Jan 3, 2023

There's a few things I want to use this for in follow-up work (notably #92607 and #92373) so if you think any of the usages in this PR are questionable then I'd rather back things out to merge this sooner instead of spending too much time iterating on this PR.

(ofc if you think the whole concept is questionable then that's worth discussing here 😁)

@thecoop
Copy link
Member

thecoop commented Jan 5, 2023

It's a good idea, but I'm concerned about the syntax here. I think it's hiding too much behind Releasable and try-with-resources - especially the fact that the ref counting can persist past the try block, depending on what the other async tasks are doing. That seems counter to what try-with-resources are meant for.

I think it needs to be more explicit in what it's doing in the code, and not use Releasable for syntactic sugar.

@DaveCTurner
Copy link
Contributor Author

@elasticmachine please run elasticsearch-ci/part-2

@DaveCTurner DaveCTurner requested a review from thecoop January 9, 2023 10:41
Copy link
Member

@thecoop thecoop left a comment

Choose a reason for hiding this comment

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

Looks good, nice change

@DaveCTurner
Copy link
Contributor Author

Thanks Simon!

@DaveCTurner DaveCTurner added the auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) label Jan 9, 2023
@elasticsearchmachine elasticsearchmachine merged commit 7a5dca0 into elastic:main Jan 9, 2023
@DaveCTurner DaveCTurner deleted the 2023-01-03-RefCountingRunnable branch January 9, 2023 12:22
DaveCTurner added a commit to DaveCTurner/elasticsearch that referenced this pull request Jan 10, 2023
Similar to the `RefCountingRunnable` introduced in elastic#92620, this commit
introduces `RefCountingListener` which wraps an `ActionListener<Void>`
and allows callers to acquire a dynamic collection of subsidiary
listeners. The `RefCountingListener` counts responses and collects
exceptions passed to these subsidiary listeners, and completes the
wrapped listener once all acquired listeners are complete.

Unlike a `CountDownActionListener` or a `GroupedActionListener`, this
mechanism avoids the need for callers to declare up-front the number of
times the listener will be completed, saving effort in computing this
number ahead of time and avoiding the need to sometimes supply an
overestimate and then make up the difference with additional artificial
completions.
DaveCTurner added a commit to DaveCTurner/elasticsearch that referenced this pull request Jan 17, 2023
Recent improvements to the primitives for writing async code
(particularly elastic#92452 and elastic#92620) mean that we can enormously simplify
`TransportNodesAction`. In particular, we can avoid accumulating an
intermediate array of responses for later processing in favour of just
accumulating the successes and failures into their final separate lists.
We also no longer need to use a separate `NodesResponseTracker` to
discard responses on cancellation.
DaveCTurner added a commit that referenced this pull request Jan 19, 2023
Recent improvements to the primitives for writing async code
(particularly #92452 and #92620) mean that we can enormously simplify
`TransportNodesAction`. In particular, we can avoid accumulating an
intermediate array of responses for later processing in favour of just
accumulating the successes and failures into their final separate lists.
We also no longer need to use a separate `NodesResponseTracker` to
discard responses on cancellation.
DaveCTurner added a commit to DaveCTurner/elasticsearch that referenced this pull request Feb 2, 2023
Similarly to elastic#92987, recent improvements to the primitives for writing
async code (particularly elastic#92452 and elastic#92620) mean that we can enormously
simplify `TransportBroadcastByNodeAction`. In particular, we can avoid
accumulating an intermediate array of responses for later processing in
favour of just accumulating the successes and failures into their final
separate lists. We also no longer need to use a separate
`NodesResponseTracker` to discard responses on cancellation. Finally, we
can now discard shard-level responses more promptly on cancellation.
elasticsearchmachine pushed a commit that referenced this pull request Feb 7, 2023
Similarly to #92987, recent improvements to the primitives for writing
async code (particularly #92452 and #92620) mean that we can enormously
simplify `TransportBroadcastByNodeAction`. In particular, we can avoid
accumulating an intermediate array of responses for later processing in
favour of just accumulating the successes and failures into their final
separate lists. We also no longer need to use a separate
`NodesResponseTracker` to discard responses on cancellation. Finally, we
can now discard shard-level responses more promptly on cancellation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) :Core/Infra/Core Core issues without another label >refactoring Team:Core/Infra Meta label for core/infra team v8.7.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants