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

[RCI] Add IndexShardOperationPermits.asyncBlockOperations(ActionListener<Releasable>) #34902

Merged
merged 4 commits into from Nov 8, 2018

Conversation

tlrx
Copy link
Member

@tlrx tlrx commented Oct 26, 2018

The current implementation of asyncBlockOperations() can be used to execute some code once all indexing operations permits have been acquired, then releases all permits immediately after the code execution. This immediate release is not suitable for treatments that need to keep all permits over multiple execution steps.

This commit adds a new asyncBlockOperations() that exposes a Releasable, making it possible to acquire all permits and only release them all when needed by closing the releasable.

This method is aimed to be used in a TransportReplicationAction that will acquire all permits on the primary shard.

The existing blockOperations() and asyncBlockOperations() methods have been modified to delegate permit acquisition/releasing to this new method.

Relates to #33888

@tlrx tlrx added >enhancement :Distributed/Engine Anything around managing Lucene and the Translog in an open shard. labels Oct 26, 2018
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-distributed

Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

Looks great. I left some suggestions. I think this can go into master to reduce the maintenance overhead.

@@ -123,23 +123,66 @@ public void close() {
* @param onFailure the action to run if a failure occurs while blocking operations
* @param <E> the type of checked exception thrown by {@code onBlocked} (not thrown on the calling thread)
*/
<E extends Exception> void asyncBlockOperations(
final long timeout, final TimeUnit timeUnit, final CheckedRunnable<E> onBlocked, final Consumer<Exception> onFailure) {
<E extends Exception> void asyncBlockOperations(final long timeout, final TimeUnit timeUnit,
Copy link
Contributor

Choose a reason for hiding this comment

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

since we only have one user of this api, I wonder wether we should just remove this syntactic sugar method and put the single user to the other api

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, let's do this.

@@ -104,8 +104,8 @@ public void close() {
final TimeUnit timeUnit,
final CheckedRunnable<E> onBlocked) throws InterruptedException, TimeoutException, E {
delayOperations();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can fold delayOperations and releaseDelayedOperations into acquireAll which will simplify the code here and in asyncBlockOperations

Copy link
Member Author

Choose a reason for hiding this comment

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

In the case of asyncBlockOperations() we want to delay operations immediately and if we fold delayOperations() into acquireAll(), operations would start to be queued when the runnable is executed by the generic thread pool, not immediately - or am I missing something?

Copy link
Contributor

Choose a reason for hiding this comment

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

I missed that. Fair point.

@tlrx tlrx changed the base branch from replicated-closed-indices to master November 5, 2018 12:20
@tlrx tlrx changed the base branch from master to replicated-closed-indices November 5, 2018 12:21
@tlrx
Copy link
Member Author

tlrx commented Nov 5, 2018

@bleskes I updated the code and removed the previous asyncBlockOperations so that there's only one async method now. I'm also OK to merge this into master directly, I'll change the target branch once this is fully reviewed. Can you have another look please?

@tlrx tlrx changed the base branch from replicated-closed-indices to master November 6, 2018 15:49
@tlrx tlrx force-pushed the indexing-ops-permits-with-releasable branch from 2554506 to 9b456e0 Compare November 6, 2018 15:50
@tlrx
Copy link
Member Author

tlrx commented Nov 6, 2018

Rebased on top of master to make CI happy.

@tlrx tlrx mentioned this pull request Nov 7, 2018
50 tasks
Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

LGTM. Left some minor suggestions. No need for another run.

@Override
public void onFailure(final Exception e) {
onFailure.accept(e);
try {
onAcquired.onFailure(e);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is interesting choice. I think I prefer to release delayed operations first, then call the onFailure handler. I don't think people can expect operations to continue being delayed and it's safer not to.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've done this to keep the previous behavior of the asyncBlockOperations() where operations were released in the onAfter() method, so after the failure handler has been called.

But I share your opinion so I changed the onFailure logic to release operations first.

e -> {
permits.asyncBlockOperations(new ActionListener<Releasable>() {
@Override
public void onResponse(final Releasable releasable) {
Copy link
Contributor

Choose a reason for hiding this comment

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

we use this pattern often - maybe introduce a simple class that wraps a runnable and runs it while releasing the releasable?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure

@tlrx tlrx force-pushed the indexing-ops-permits-with-releasable branch from dcc8abe to 16e2967 Compare November 7, 2018 12:02
…ner<Releasable>)

The current implementation of asyncBlockOperations() can be used to
execute some code once all indexing operations permits have been acquired,
 then releases all permits immediately after the code execution. This
 immediate release is not suitable for treatments that need to keep all
 permits over multiple execution steps.

This commit adds a new asyncBlockOperations() that exposes a Releasable,
 making it possible to acquire all permits and only release them all
 when needed by closing the Releasable.

This method is aimed to be used in a TransportReplicationAction that
 will acquire all permits on the primary shard.

The existing blockOperations() and asyncBlockOperations() methods have
been modified to delegate permit acquisition/releasing to this new
method.

Relates to elastic#33888
@tlrx tlrx force-pushed the indexing-ops-permits-with-releasable branch from 16e2967 to ef1a506 Compare November 7, 2018 12:50
Copy link
Contributor

@s1monw s1monw 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 left some suggestions

@tlrx tlrx merged commit 1703a61 into elastic:master Nov 8, 2018
@tlrx tlrx deleted the indexing-ops-permits-with-releasable branch November 8, 2018 08:23
@tlrx
Copy link
Member Author

tlrx commented Nov 8, 2018

Thanks @bleskes @s1monw

jasontedor added a commit to jasontedor/elasticsearch that referenced this pull request Nov 8, 2018
* elastic/master: (25 commits)
  Fixes fast vector highlighter docs per issue 24318. (elastic#34190)
  [ML] Prevent notifications on deletion of a non existent job (elastic#35337)
  [CCR] Auto follow Coordinator fetch cluster state in system context (elastic#35120)
  Mute test for elastic#35361
  Preserve `date_histogram` format when aggregating on unmapped fields (elastic#35254)
  Test: Mute failing SSL test
  Allow unmapped fields in composite aggregations (elastic#35331)
  [RCI] Add IndexShardOperationPermits.asyncBlockOperations(ActionListener<Releasable>) (elastic#34902)
  HLRC: reindex API with wait_for_completion false (elastic#35202)
  Add docs on JNA temp directory not being noexec (elastic#35355)
  [CCR] Adjust list of dynamic index settings that should be replicated (elastic#35195)
  Replicate index settings to followers (elastic#35089)
  Rename RealmConfig.globalSettings() to settings() (elastic#35330)
  [TEST] Cleanup FileUserPasswdStoreTests (elastic#35329)
  Scripting: Add back lookup vars in score script (elastic#34833)
  watcher: Fix integration tests to ensure correct start/stop of Watcher (elastic#35271)
  Remove ALL shard check in CheckShrinkReadyStep (elastic#35346)
  Use soft-deleted docs to resolve strategy for engine operation (elastic#35230)
  [ILM] Check shard and relocation status in AllocationRoutedStep (elastic#35316)
  Ignore date ranges containing 'now' when pre-processing a percolator query (elastic#35160)
  ...
@pcsanwald
Copy link
Contributor

@tlrx I added v7.0.0 label here, please remove if that seems wrong.

@tlrx
Copy link
Member Author

tlrx commented Nov 9, 2018

Thanks @pcsanwald and sorry - it was intended to be merged in a feature branch and then we decided that it could go in master but I forgot to add the version label.

pgomulka pushed a commit to pgomulka/elasticsearch that referenced this pull request Nov 13, 2018
…ner<Releasable>) (elastic#34902)

The current implementation of asyncBlockOperations() can be used to
execute some code once all indexing operations permits have been acquired,
 then releases all permits immediately after the code execution. This
 immediate release is not suitable for treatments that need to keep all
 permits over multiple execution steps.

This commit adds a new asyncBlockOperations() that exposes a Releasable,
 making it possible to acquire all permits and only release them all
 when needed by closing the Releasable. The existing blockOperations() 
method has been modified to delegate permit acquisition/releasing to this new
method.

Relates to elastic#33888
tlrx added a commit that referenced this pull request Nov 14, 2018
…ner<Releasable>) (#34902)

The current implementation of asyncBlockOperations() can be used to
execute some code once all indexing operations permits have been acquired,
 then releases all permits immediately after the code execution. This
 immediate release is not suitable for treatments that need to keep all
 permits over multiple execution steps.

This commit adds a new asyncBlockOperations() that exposes a Releasable,
 making it possible to acquire all permits and only release them all
 when needed by closing the Releasable. The existing blockOperations() 
method has been modified to delegate permit acquisition/releasing to this new
method.

Relates to #33888
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed/Engine Anything around managing Lucene and the Translog in an open shard. >enhancement v6.6.0 v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants