- Notifications
You must be signed in to change notification settings - Fork 25.6k
Tidy up PlainListenableActionFuture #68735
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
Tidy up PlainListenableActionFuture #68735
Conversation
As of elastic#53261 today `PlainListenableActionFuture` is the sole implementation of `ListenableActionFuture`, the reason for the `Plain...` prefix is now lost. It also heavily uses variable shadowing in its implementation which makes it quite hard to read, uses a mix of `volatile` fields and mutexes, and keeps hold of the deferred listeners even after completion. Finally it does not have many tests. This commit drops the unnecessary interface and renames the class to simply `ListenableActionFuture`. It reworks the implementation to avoid shadowing variables, drops the deferred listeners on completion, and moves to an entirely mutex-based implementation. Finally, it adds another test that it works as advertised.
| Pinging @elastic/es-core-infra (Team:Core/Infra) |
| synchronized (this) { | ||
| executedListeners = true; | ||
| } | ||
| Object listeners = this.listeners; |
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.
This is the only volatile read outside of the mutex, but we just had the mutex anyway, may as well move this up a line and drop the volatile.
| if (executedListeners) { | ||
| executeImmediate = true; | ||
| } else { | ||
| Object listeners = this.listeners; |
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.
Reworked this to have better names and to use final variables throughout, which introduces one extra local variable but makes it all a lot clearer.
| | ||
| @Override | ||
| public void addListener(final ActionListener<T> listener) { | ||
| internalAddListener(listener); |
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.
The only caller of internalAddListener, inlined it.
henningandersen left a comment
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.
Nice cleanup, LGTM.
As of #53261 today `PlainListenableActionFuture` is the sole implementation of `ListenableActionFuture`, the reason for the `Plain...` prefix is now lost. It also heavily uses variable shadowing in its implementation which makes it quite hard to read, uses a mix of `volatile` fields and mutexes, and keeps hold of the deferred listeners even after completion. Finally it does not have many tests. This commit drops the unnecessary interface and renames the class to simply `ListenableActionFuture`. It reworks the implementation to avoid shadowing variables, drops the deferred listeners on completion, and moves to an entirely mutex-based implementation. Finally, it adds another test that it works as advertised.
As of #53261 today
PlainListenableActionFutureis the soleimplementation of
ListenableActionFuture, the reason for thePlain...prefix is now lost. It also heavily uses variable shadowingin its implementation which makes it quite hard to read, uses a mix of
volatilefields and mutexes, and keeps hold of the deferred listenerseven after completion. Finally it does not have many tests.
This commit drops the unnecessary interface and renames the class to
simply
ListenableActionFuture. It reworks the implementation to avoidshadowing variables, drops the deferred listeners on completion, and
moves to an entirely mutex-based implementation. Finally, it adds
another test that it works as advertised.