{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/51392960","id":51392960,"diff_hunk":"@@ -0,0 +1,128 @@\n+/*\n+ * Licensed to Elasticsearch under one or more contributor\n+ * license agreements. See the NOTICE file distributed with\n+ * this work for additional information regarding copyright\n+ * ownership. Elasticsearch licenses this file to you under\n+ * the Apache License, Version 2.0 (the \"License\"); you may\n+ * not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *    http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied.  See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ */\n+\n+package org.elasticsearch.tasks;\n+\n+import org.elasticsearch.common.collect.Tuple;\n+import org.elasticsearch.common.inject.Provider;\n+\n+import java.util.concurrent.atomic.AtomicReference;\n+\n+/**\n+ * A task that can be canceled\n+ */\n+public class CancellableTask extends Task {\n+\n+    private final boolean hasChildren;\n+\n+    private static final Tuple<String, CancellationListener> TASK_FINISHED_MARKER = new Tuple<>(\"task finished\", null);\n+\n+    private static ThreadLocal<CancellableTask> current = new ThreadLocal<>();\n+\n+    public static void setCurrent(CancellableTask value) {\n+        current.set(value);\n+    }\n+\n+    public static void removeCurrent() {\n+        current.remove();\n+    }\n+\n+    public static void checkCurrent() {\n+        current.get().check();\n+    }\n+\n+    private AtomicReference<Tuple<String, CancellationListener>> cancellationReasonAndListener = new AtomicReference<>();\n+\n+    public CancellableTask(long id, String type, String action, Provider<String> description, boolean hasChildren) {\n+        super(id, type, action, description);\n+        this.hasChildren = hasChildren;\n+    }\n+\n+    public CancellableTask(long id, String type, String action, Provider<String> description, String parentNode, long parentId, boolean hasChildren) {\n+        super(id, type, action, description, parentNode, parentId);\n+        this.hasChildren = hasChildren;\n+    }\n+\n+    public boolean hasChildren() {\n+        return hasChildren;\n+    }\n+\n+    public final boolean cancel(String reason, CancellationListener listener) {\n+        if (cancellationReasonAndListener.compareAndSet(null, new Tuple<>(reason, listener))) {\n+            try {\n+                doCancel(reason);\n+            } catch (Throwable ex) {\n+                // What to do?","path":"core/src/main/java/org/elasticsearch/tasks/CancellableTask.java","position":71,"original_position":71,"commit_id":"ecd233653bd916023b45d32a273d3e21237627c5","original_commit_id":"ecd233653bd916023b45d32a273d3e21237627c5","user":{"login":"s1monw","id":973334,"avatar_url":"https://avatars.githubusercontent.com/u/973334?v=3","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":"what about barf?","created_at":"2016-02-01T09:04:38Z","updated_at":"2016-02-01T09:04:38Z","html_url":"https://github.com/elastic/elasticsearch/pull/16320#discussion_r51392960","pull_request_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320","_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/51392960"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/16320#discussion_r51392960"},"pull_request":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320","id":57699034,"html_url":"https://github.com/elastic/elasticsearch/pull/16320","diff_url":"https://github.com/elastic/elasticsearch/pull/16320.diff","patch_url":"https://github.com/elastic/elasticsearch/pull/16320.patch","issue_url":"https://api.github.com/repos/elastic/elasticsearch/issues/16320","number":16320,"state":"open","locked":false,"title":"Add task cancellation mechanism","user":{"login":"imotov","id":655851,"avatar_url":"https://avatars.githubusercontent.com/u/655851?v=3","gravatar_id":"","url":"https://api.github.com/users/imotov","html_url":"https://github.com/imotov","followers_url":"https://api.github.com/users/imotov/followers","following_url":"https://api.github.com/users/imotov/following{/other_user}","gists_url":"https://api.github.com/users/imotov/gists{/gist_id}","starred_url":"https://api.github.com/users/imotov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imotov/subscriptions","organizations_url":"https://api.github.com/users/imotov/orgs","repos_url":"https://api.github.com/users/imotov/repos","events_url":"https://api.github.com/users/imotov/events{/privacy}","received_events_url":"https://api.github.com/users/imotov/received_events","type":"User","site_admin":false},"body":"Only tasks that extend CancellableTask can be cancelled using this mechanism. If a cancellable task has children it can elect to cancel all child tasks as well. In this case a special ban parent request is sent to all nodes. This request does two things: 1) it prevents any tasks with the banned parent task from being started, and 2) it cancels all currently running tasks that have the banned task as a parent. The ban is lifted as soon as the coordinating node notifies all other nodes that the cancelled task has finished executing. If the coordinating node leaves the cluster before it has a chance to lift its bans, all bans set by this coordinating node are automatically removed.\r\n\r\nAs an option a task can elect to automatically cancel all child tasks if their parent task was running on a node that just left the cluster. This option makes sense for cancellable heavy tasks that have no side-effects and only return results to the coordinating node. With the coordinating node gone, it doesn't make sense to run such tasks any longer since their results will be most likely discarded.","created_at":"2016-01-29T20:33:47Z","updated_at":"2016-02-01T09:04:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"91f467977e2d99160a7ac21845a2e1e003119196","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320/commits","review_comments_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320/comments","review_comment_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/issues/16320/comments","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/ecd233653bd916023b45d32a273d3e21237627c5","head":{"label":"imotov:task-cancellation","ref":"task-cancellation","sha":"ecd233653bd916023b45d32a273d3e21237627c5","user":{"login":"imotov","id":655851,"avatar_url":"https://avatars.githubusercontent.com/u/655851?v=3","gravatar_id":"","url":"https://api.github.com/users/imotov","html_url":"https://github.com/imotov","followers_url":"https://api.github.com/users/imotov/followers","following_url":"https://api.github.com/users/imotov/following{/other_user}","gists_url":"https://api.github.com/users/imotov/gists{/gist_id}","starred_url":"https://api.github.com/users/imotov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imotov/subscriptions","organizations_url":"https://api.github.com/users/imotov/orgs","repos_url":"https://api.github.com/users/imotov/repos","events_url":"https://api.github.com/users/imotov/events{/privacy}","received_events_url":"https://api.github.com/users/imotov/received_events","type":"User","site_admin":false},"repo":{"id":1484646,"name":"elasticsearch","full_name":"imotov/elasticsearch","owner":{"login":"imotov","id":655851,"avatar_url":"https://avatars.githubusercontent.com/u/655851?v=3","gravatar_id":"","url":"https://api.github.com/users/imotov","html_url":"https://github.com/imotov","followers_url":"https://api.github.com/users/imotov/followers","following_url":"https://api.github.com/users/imotov/following{/other_user}","gists_url":"https://api.github.com/users/imotov/gists{/gist_id}","starred_url":"https://api.github.com/users/imotov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imotov/subscriptions","organizations_url":"https://api.github.com/users/imotov/orgs","repos_url":"https://api.github.com/users/imotov/repos","events_url":"https://api.github.com/users/imotov/events{/privacy}","received_events_url":"https://api.github.com/users/imotov/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/imotov/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":true,"url":"https://api.github.com/repos/imotov/elasticsearch","forks_url":"https://api.github.com/repos/imotov/elasticsearch/forks","keys_url":"https://api.github.com/repos/imotov/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/imotov/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/imotov/elasticsearch/teams","hooks_url":"https://api.github.com/repos/imotov/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/imotov/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/imotov/elasticsearch/events","assignees_url":"https://api.github.com/repos/imotov/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/imotov/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/imotov/elasticsearch/tags","blobs_url":"https://api.github.com/repos/imotov/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/imotov/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/imotov/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/imotov/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/imotov/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/imotov/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/imotov/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/imotov/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/imotov/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/imotov/elasticsearch/subscription","commits_url":"https://api.github.com/repos/imotov/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/imotov/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/imotov/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/imotov/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/imotov/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/imotov/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/imotov/elasticsearch/merges","archive_url":"https://api.github.com/repos/imotov/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/imotov/elasticsearch/downloads","issues_url":"https://api.github.com/repos/imotov/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/imotov/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/imotov/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/imotov/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/imotov/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/imotov/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/imotov/elasticsearch/deployments","created_at":"2011-03-15T21:12:02Z","updated_at":"2015-12-21T11:41:57Z","pushed_at":"2016-01-29T20:28:44Z","git_url":"git://github.com/imotov/elasticsearch.git","ssh_url":"git@github.com:imotov/elasticsearch.git","clone_url":"https://github.com/imotov/elasticsearch.git","svn_url":"https://github.com/imotov/elasticsearch","homepage":"http://elasticsearch.org","size":165633,"stargazers_count":2,"watchers_count":2,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"elastic:master","ref":"master","sha":"23f70296fb85b346b8c1f72579cac91d3d6279ab","user":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","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,"name":"elasticsearch","full_name":"elastic/elasticsearch","owner":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","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},"private":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":"2016-02-01T09:04:30Z","pushed_at":"2016-02-01T08:51:50Z","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":286293,"stargazers_count":14867,"watchers_count":14867,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":4912,"mirror_url":null,"open_issues_count":1132,"forks":4912,"open_issues":1132,"watchers":14867,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/16320"},"issue":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/16320"},"comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/16320/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/16320/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/elasticsearch/statuses/ecd233653bd916023b45d32a273d3e21237627c5"}}}}