{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/231489785","pull_request_review_id":172468141,"id":231489785,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMTQ4OTc4NQ==","diff_hunk":"@@ -104,42 +103,54 @@ public void close() {\n             final TimeUnit timeUnit,\n             final CheckedRunnable<E> onBlocked) throws InterruptedException, TimeoutException, E {\n         delayOperations();\n-        try {\n-            doBlockOperations(timeout, timeUnit, onBlocked);\n+        try (Releasable ignored = acquireAll(timeout, timeUnit)) {\n+            onBlocked.run();\n         } finally {\n             releaseDelayedOperations();\n         }\n     }\n \n     /**\n-     * Immediately delays operations and on another thread waits for in-flight operations to finish and then executes {@code onBlocked}\n-     * under the guarantee that no new operations are started. Delayed operations are run after {@code onBlocked} has executed. After\n-     * operations are delayed and the blocking is forked to another thread, returns to the caller. If a failure occurs while blocking\n-     * operations or executing {@code onBlocked} then the {@code onFailure} handler will be invoked.\n+     * Immediately delays operations and on another thread waits for in-flight operations to finish and then acquires all permits. When all\n+     * permits are acquired, the provided {@link ActionListener} is called under the guarantee that no new operations are started. Delayed\n+     * operations are run once the {@link Releasable} is released or if a failure occurs while acquiring all permits; in this case the\n+     * {@code onFailure} handler will be invoked after delayed operations are released.\n      *\n-     * @param timeout   the maximum time to wait for the in-flight operations block\n-     * @param timeUnit  the time unit of the {@code timeout} argument\n-     * @param onBlocked the action to run once the block has been acquired\n-     * @param onFailure the action to run if a failure occurs while blocking operations\n-     * @param <E>       the type of checked exception thrown by {@code onBlocked} (not thrown on the calling thread)\n+     * @param onAcquired {@link ActionListener} that is invoked once acquisition is successful or failed\n+     * @param timeout    the maximum time to wait for the in-flight operations block\n+     * @param timeUnit   the time unit of the {@code timeout} argument\n      */\n-    <E extends Exception> void asyncBlockOperations(\n-            final long timeout, final TimeUnit timeUnit, final CheckedRunnable<E> onBlocked, final Consumer<Exception> onFailure) {\n+    public void asyncBlockOperations(final ActionListener<Releasable> onAcquired, final long timeout, final TimeUnit timeUnit)  {\n         delayOperations();\n         threadPool.executor(ThreadPool.Names.GENERIC).execute(new AbstractRunnable() {\n+\n+            final AtomicBoolean released = new AtomicBoolean(false);\n+\n             @Override\n             public void onFailure(final Exception e) {\n-                onFailure.accept(e);\n+                try {","path":"server/src/main/java/org/elasticsearch/index/shard/IndexShardOperationPermits.java","position":51,"original_position":51,"commit_id":"ef1a506f9f5f4e0a39e78a3e319e760e295d834c","original_commit_id":"16e29670d5afd74a4f96482840064c3da03aa25c","user":{"login":"s1monw","id":973334,"node_id":"MDQ6VXNlcjk3MzMzNA==","avatar_url":"https://avatars0.githubusercontent.com/u/973334?v=4","gravatar_id":"","url":"https://api.github.com/users/s1monw","html_url":"https://github.com/s1monw","followers_url":"https://api.github.com/users/s1monw/followers","following_url":"https://api.github.com/users/s1monw/following{/other_user}","gists_url":"https://api.github.com/users/s1monw/gists{/gist_id}","starred_url":"https://api.github.com/users/s1monw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s1monw/subscriptions","organizations_url":"https://api.github.com/users/s1monw/orgs","repos_url":"https://api.github.com/users/s1monw/repos","events_url":"https://api.github.com/users/s1monw/events{/privacy}","received_events_url":"https://api.github.com/users/s1monw/received_events","type":"User","site_admin":false},"body":"we have this pattern all over the place in ES and here twice in one file where we want to run some code once and only once. Maybe it would be nice to have a simple `RunOnce` class that takes a closure?","created_at":"2018-11-07T12:45:15Z","updated_at":"2018-11-07T12:53:10Z","html_url":"https://github.com/elastic/elasticsearch/pull/34902#discussion_r231489785","pull_request_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/231489785"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/34902#discussion_r231489785"},"pull_request":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902","id":226058805,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI2MDU4ODA1","html_url":"https://github.com/elastic/elasticsearch/pull/34902","diff_url":"https://github.com/elastic/elasticsearch/pull/34902.diff","patch_url":"https://github.com/elastic/elasticsearch/pull/34902.patch","issue_url":"https://api.github.com/repos/elastic/elasticsearch/issues/34902","number":34902,"state":"open","locked":false,"title":"[RCI] Add IndexShardOperationPermits.asyncBlockOperations(ActionListener<Releasable>)","user":{"login":"tlrx","id":642733,"node_id":"MDQ6VXNlcjY0MjczMw==","avatar_url":"https://avatars1.githubusercontent.com/u/642733?v=4","gravatar_id":"","url":"https://api.github.com/users/tlrx","html_url":"https://github.com/tlrx","followers_url":"https://api.github.com/users/tlrx/followers","following_url":"https://api.github.com/users/tlrx/following{/other_user}","gists_url":"https://api.github.com/users/tlrx/gists{/gist_id}","starred_url":"https://api.github.com/users/tlrx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tlrx/subscriptions","organizations_url":"https://api.github.com/users/tlrx/orgs","repos_url":"https://api.github.com/users/tlrx/repos","events_url":"https://api.github.com/users/tlrx/events{/privacy}","received_events_url":"https://api.github.com/users/tlrx/received_events","type":"User","site_admin":false},"body":"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.\r\n\r\nThis 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.\r\n \r\nThis method is aimed to be used in a `TransportReplicationAction` that will acquire all permits on the primary shard.\r\n    \r\nThe existing `blockOperations()` and `asyncBlockOperations()` methods have been modified to delegate permit acquisition/releasing to this new method.\r\n    \r\nRelates to #33888\r\n","created_at":"2018-10-26T11:02:34Z","updated_at":"2018-11-07T12:53:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1ff0743067cc85d5514ed1490fb72970c625d85c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":836542781,"node_id":"MDU6TGFiZWw4MzY1NDI3ODE=","url":"https://api.github.com/repos/elastic/elasticsearch/labels/:Distributed/Engine","name":":Distributed/Engine","color":"0e8a16","default":false},{"id":23174,"node_id":"MDU6TGFiZWwyMzE3NA==","url":"https://api.github.com/repos/elastic/elasticsearch/labels/%3Eenhancement","name":">enhancement","color":"4a4ea8","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902/commits","review_comments_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902/comments","review_comment_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/issues/34902/comments","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/ef1a506f9f5f4e0a39e78a3e319e760e295d834c","head":{"label":"tlrx:indexing-ops-permits-with-releasable","ref":"indexing-ops-permits-with-releasable","sha":"ef1a506f9f5f4e0a39e78a3e319e760e295d834c","user":{"login":"tlrx","id":642733,"node_id":"MDQ6VXNlcjY0MjczMw==","avatar_url":"https://avatars1.githubusercontent.com/u/642733?v=4","gravatar_id":"","url":"https://api.github.com/users/tlrx","html_url":"https://github.com/tlrx","followers_url":"https://api.github.com/users/tlrx/followers","following_url":"https://api.github.com/users/tlrx/following{/other_user}","gists_url":"https://api.github.com/users/tlrx/gists{/gist_id}","starred_url":"https://api.github.com/users/tlrx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tlrx/subscriptions","organizations_url":"https://api.github.com/users/tlrx/orgs","repos_url":"https://api.github.com/users/tlrx/repos","events_url":"https://api.github.com/users/tlrx/events{/privacy}","received_events_url":"https://api.github.com/users/tlrx/received_events","type":"User","site_admin":false},"repo":{"id":24718639,"node_id":"MDEwOlJlcG9zaXRvcnkyNDcxODYzOQ==","name":"elasticsearch","full_name":"tlrx/elasticsearch","private":false,"owner":{"login":"tlrx","id":642733,"node_id":"MDQ6VXNlcjY0MjczMw==","avatar_url":"https://avatars1.githubusercontent.com/u/642733?v=4","gravatar_id":"","url":"https://api.github.com/users/tlrx","html_url":"https://github.com/tlrx","followers_url":"https://api.github.com/users/tlrx/followers","following_url":"https://api.github.com/users/tlrx/following{/other_user}","gists_url":"https://api.github.com/users/tlrx/gists{/gist_id}","starred_url":"https://api.github.com/users/tlrx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tlrx/subscriptions","organizations_url":"https://api.github.com/users/tlrx/orgs","repos_url":"https://api.github.com/users/tlrx/repos","events_url":"https://api.github.com/users/tlrx/events{/privacy}","received_events_url":"https://api.github.com/users/tlrx/received_events","type":"User","site_admin":false},"html_url":"https://github.com/tlrx/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":true,"url":"https://api.github.com/repos/tlrx/elasticsearch","forks_url":"https://api.github.com/repos/tlrx/elasticsearch/forks","keys_url":"https://api.github.com/repos/tlrx/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tlrx/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tlrx/elasticsearch/teams","hooks_url":"https://api.github.com/repos/tlrx/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/tlrx/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/tlrx/elasticsearch/events","assignees_url":"https://api.github.com/repos/tlrx/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/tlrx/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/tlrx/elasticsearch/tags","blobs_url":"https://api.github.com/repos/tlrx/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tlrx/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tlrx/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/tlrx/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tlrx/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/tlrx/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/tlrx/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/tlrx/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/tlrx/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/tlrx/elasticsearch/subscription","commits_url":"https://api.github.com/repos/tlrx/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/tlrx/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/tlrx/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/tlrx/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/tlrx/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/tlrx/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tlrx/elasticsearch/merges","archive_url":"https://api.github.com/repos/tlrx/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tlrx/elasticsearch/downloads","issues_url":"https://api.github.com/repos/tlrx/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/tlrx/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/tlrx/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/tlrx/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tlrx/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/tlrx/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/tlrx/elasticsearch/deployments","created_at":"2014-10-02T12:51:44Z","updated_at":"2014-10-02T08:42:36Z","pushed_at":"2018-11-07T12:50:23Z","git_url":"git://github.com/tlrx/elasticsearch.git","ssh_url":"git@github.com:tlrx/elasticsearch.git","clone_url":"https://github.com/tlrx/elasticsearch.git","svn_url":"https://github.com/tlrx/elasticsearch","homepage":"http://elasticsearch.org","size":381233,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"elastic:master","ref":"master","sha":"e685cfe8f985e1669b0594bbd5b2300c35d8bbb9","user":{"login":"elastic","id":6764390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY3NjQzOTA=","avatar_url":"https://avatars0.githubusercontent.com/u/6764390?v=4","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"repo":{"id":507775,"node_id":"MDEwOlJlcG9zaXRvcnk1MDc3NzU=","name":"elasticsearch","full_name":"elastic/elasticsearch","private":false,"owner":{"login":"elastic","id":6764390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY3NjQzOTA=","avatar_url":"https://avatars0.githubusercontent.com/u/6764390?v=4","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/elastic/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":false,"url":"https://api.github.com/repos/elastic/elasticsearch","forks_url":"https://api.github.com/repos/elastic/elasticsearch/forks","keys_url":"https://api.github.com/repos/elastic/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elastic/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elastic/elasticsearch/teams","hooks_url":"https://api.github.com/repos/elastic/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/elastic/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/elastic/elasticsearch/events","assignees_url":"https://api.github.com/repos/elastic/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/elastic/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/elastic/elasticsearch/tags","blobs_url":"https://api.github.com/repos/elastic/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elastic/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elastic/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/elastic/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/elastic/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/elastic/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/elastic/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/elastic/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/elastic/elasticsearch/subscription","commits_url":"https://api.github.com/repos/elastic/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/elastic/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/elastic/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/elastic/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/elastic/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elastic/elasticsearch/merges","archive_url":"https://api.github.com/repos/elastic/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elastic/elasticsearch/downloads","issues_url":"https://api.github.com/repos/elastic/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/elastic/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/elastic/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/elastic/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elastic/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/elastic/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/elastic/elasticsearch/deployments","created_at":"2010-02-08T13:20:56Z","updated_at":"2018-11-07T12:24:30Z","pushed_at":"2018-11-07T12:50:27Z","git_url":"git://github.com/elastic/elasticsearch.git","ssh_url":"git@github.com:elastic/elasticsearch.git","clone_url":"https://github.com/elastic/elasticsearch.git","svn_url":"https://github.com/elastic/elasticsearch","homepage":"https://www.elastic.co/products/elasticsearch","size":528982,"stargazers_count":35873,"watchers_count":35873,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":12097,"mirror_url":null,"archived":false,"open_issues_count":1759,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":12097,"open_issues":1759,"watchers":35873,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/34902"},"issue":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/34902"},"comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/34902/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/34902/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/elasticsearch/statuses/ef1a506f9f5f4e0a39e78a3e319e760e295d834c"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"s1monw"}}