-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Adding a cancelled field to tell if a cancellable task is cancelled #1682
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
Changes from all commits
c60caef
c0f8384
9121895
ebb2ab1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,11 @@ | |
|
|
||
| package org.opensearch.tasks; | ||
|
|
||
| <<<<<<< HEAD | ||
| ======= | ||
|
Comment on lines
+35
to
+36
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merge problem? |
||
| import org.opensearch.Version; | ||
| import org.opensearch.LegacyESVersion; | ||
| >>>>>>> c0f838439041b18b511ec6c5b42bac033ff1753f | ||
| import org.opensearch.common.ParseField; | ||
| import org.opensearch.common.Strings; | ||
| import org.opensearch.common.bytes.BytesReference; | ||
|
|
@@ -79,6 +84,8 @@ public final class TaskInfo implements Writeable, ToXContentFragment { | |
|
|
||
| private final boolean cancellable; | ||
|
|
||
| private final boolean cancelled; | ||
|
|
||
| private final TaskId parentTaskId; | ||
|
|
||
| private final Map<String, String> headers; | ||
|
|
@@ -92,9 +99,11 @@ public TaskInfo( | |
| long startTime, | ||
| long runningTimeNanos, | ||
| boolean cancellable, | ||
| boolean cancelled, | ||
| TaskId parentTaskId, | ||
| Map<String, String> headers | ||
| ) { | ||
| assert cancellable || cancelled == false : "uncancellable task cannot be cancelled"; | ||
| this.taskId = taskId; | ||
| this.type = type; | ||
| this.action = action; | ||
|
|
@@ -103,6 +112,7 @@ public TaskInfo( | |
| this.startTime = startTime; | ||
| this.runningTimeNanos = runningTimeNanos; | ||
| this.cancellable = cancellable; | ||
| this.cancelled = cancelled; | ||
| this.parentTaskId = parentTaskId; | ||
| this.headers = headers; | ||
| } | ||
|
|
@@ -119,6 +129,12 @@ public TaskInfo(StreamInput in) throws IOException { | |
| startTime = in.readLong(); | ||
| runningTimeNanos = in.readLong(); | ||
| cancellable = in.readBoolean(); | ||
| if (in.getVersion().onOrAfter(Version.V_2_0_0)) { | ||
| cancelled = in.readBoolean(); | ||
| } else { | ||
| cancelled = false; | ||
| } | ||
| assert cancellable || cancelled == false : "uncancellable task cannot be cancelled"; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure assert is the right thing to do here. An AssertionError (because it is a child of error) "indicates serious problems that a reasonable application should not try to catch". This is constructing an object from parsing a stream, so are there contexts where external input could trigger this path? If so, we definitely don't want the application to throw an Error. IllegalArgumentException seems more appropriate to me.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might trigger in those cases where we are trying to cancel a task which cannot be cancelled when cancelled is true and cancellable is false. But as you mentioned we can throw a IllegalArgumentException instead of the assert error. |
||
| parentTaskId = TaskId.readFromStream(in); | ||
| headers = in.readMap(StreamInput::readString, StreamInput::readString); | ||
| } | ||
|
|
@@ -133,6 +149,9 @@ public void writeTo(StreamOutput out) throws IOException { | |
| out.writeLong(startTime); | ||
| out.writeLong(runningTimeNanos); | ||
| out.writeBoolean(cancellable); | ||
| if (out.getVersion().onOrAfter(Version.V_2_0_0)) { | ||
| out.writeBoolean(cancelled); | ||
| } | ||
| parentTaskId.writeTo(out); | ||
| out.writeMap(headers, StreamOutput::writeString, StreamOutput::writeString); | ||
| } | ||
|
|
@@ -186,6 +205,13 @@ public boolean isCancellable() { | |
| return cancellable; | ||
| } | ||
|
|
||
| /** | ||
| * Returns true if the task has been cancelled | ||
| */ | ||
| public boolean isCancelled() { | ||
| return cancelled; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the parent task id | ||
| */ | ||
|
|
@@ -218,6 +244,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws | |
| } | ||
| builder.field("running_time_in_nanos", runningTimeNanos); | ||
| builder.field("cancellable", cancellable); | ||
| builder.field("cancelled", cancelled); | ||
| if (parentTaskId.isSet()) { | ||
| builder.field("parent_task_id", parentTaskId.toString()); | ||
| } | ||
|
|
@@ -243,6 +270,7 @@ public static TaskInfo fromXContent(XContentParser parser) { | |
| long startTime = (Long) a[i++]; | ||
| long runningTimeNanos = (Long) a[i++]; | ||
| boolean cancellable = (Boolean) a[i++]; | ||
| boolean cancelled = a[i++] == Boolean.TRUE; | ||
| String parentTaskIdString = (String) a[i++]; | ||
| @SuppressWarnings("unchecked") | ||
| Map<String, String> headers = (Map<String, String>) a[i++]; | ||
|
|
@@ -252,7 +280,19 @@ public static TaskInfo fromXContent(XContentParser parser) { | |
| } | ||
| RawTaskStatus status = statusBytes == null ? null : new RawTaskStatus(statusBytes); | ||
| TaskId parentTaskId = parentTaskIdString == null ? TaskId.EMPTY_TASK_ID : new TaskId(parentTaskIdString); | ||
| return new TaskInfo(id, type, action, description, status, startTime, runningTimeNanos, cancellable, parentTaskId, headers); | ||
| return new TaskInfo( | ||
| id, | ||
| type, | ||
| action, | ||
| description, | ||
| status, | ||
| startTime, | ||
| runningTimeNanos, | ||
| cancellable, | ||
| cancelled, | ||
| parentTaskId, | ||
| headers | ||
| ); | ||
| }); | ||
| static { | ||
| // Note for the future: this has to be backwards and forwards compatible with all changes to the task storage format | ||
|
|
@@ -266,6 +306,7 @@ public static TaskInfo fromXContent(XContentParser parser) { | |
| PARSER.declareLong(constructorArg(), new ParseField("start_time_in_millis")); | ||
| PARSER.declareLong(constructorArg(), new ParseField("running_time_in_nanos")); | ||
| PARSER.declareBoolean(constructorArg(), new ParseField("cancellable")); | ||
| PARSER.declareBoolean(optionalConstructorArg(), new ParseField("cancelled")); | ||
| PARSER.declareString(optionalConstructorArg(), new ParseField("parent_task_id")); | ||
| PARSER.declareObject(optionalConstructorArg(), (p, c) -> p.mapStrings(), new ParseField("headers")); | ||
| } | ||
|
|
@@ -290,12 +331,25 @@ public boolean equals(Object obj) { | |
| && Objects.equals(runningTimeNanos, other.runningTimeNanos) | ||
| && Objects.equals(parentTaskId, other.parentTaskId) | ||
| && Objects.equals(cancellable, other.cancellable) | ||
| && Objects.equals(cancelled, other.cancelled) | ||
| && Objects.equals(status, other.status) | ||
| && Objects.equals(headers, other.headers); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(taskId, type, action, description, startTime, runningTimeNanos, parentTaskId, cancellable, status, headers); | ||
| return Objects.hash( | ||
| taskId, | ||
| type, | ||
| action, | ||
| description, | ||
| startTime, | ||
| runningTimeNanos, | ||
| parentTaskId, | ||
| cancellable, | ||
| cancelled, | ||
| status, | ||
| headers | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,9 @@ | |
| "cancellable": { | ||
| "type": "boolean" | ||
| }, | ||
| "cancelled": { | ||
| "type": "boolean" | ||
| }, | ||
| "id": { | ||
| "type": "long" | ||
| }, | ||
|
|
||
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.
I don't know to be honest why this method is final, but it certainly looks like it should not be and should be overridden by
CancellableTask, without the need to useinstanceofand type casting.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.
Agreed. It seems to defeat the purpose of inheritance to have a parent class check at runtime whether it is an instance of a child class.