-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Add resource stats to task framework #1555
Changes from 1 commit
4744ffe
071e56b
dcbbf5b
6c845dd
eb3e993
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 |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.tasks; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class StatCollectorTask extends CancellableTask { | ||
sruti1312 marked this conversation as resolved.
Show resolved
Hide resolved
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.
|
||
private Map<String, Long> allStats; | ||
|
||
public StatCollectorTask(long id, String type, String action, String description, TaskId parentTaskId, Map<String, String> headers) { | ||
super(id, type, action, description, parentTaskId, headers); | ||
allStats = new HashMap<>(); | ||
} | ||
|
||
@Override | ||
public boolean shouldCancelChildrenOnCancellation() { | ||
return false; | ||
} | ||
|
||
public Map<String, Long> getStats() { | ||
return allStats; | ||
} | ||
|
||
public void updateStat(TaskStatsType statsType, long value) { | ||
allStats.put(statsType.toString(), value); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ | |
import org.opensearch.common.xcontent.ToXContentObject; | ||
|
||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
/** | ||
|
@@ -131,7 +132,8 @@ protected final TaskInfo taskInfo(String localNodeId, String description, Status | |
System.nanoTime() - startTimeNanos, | ||
this instanceof CancellableTask, | ||
parentTask, | ||
headers | ||
headers, | ||
this instanceof StatCollectorTask ? ((StatCollectorTask) this).getStats() : Collections.emptyMap() | ||
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. We are using empty map as default for |
||
); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,6 +84,8 @@ public final class TaskInfo implements Writeable, ToXContentFragment { | |
|
||
private final Map<String, String> headers; | ||
|
||
private final Map<String, Long> statsInfo; | ||
|
||
public TaskInfo( | ||
TaskId taskId, | ||
String type, | ||
|
@@ -94,7 +96,8 @@ public TaskInfo( | |
long runningTimeNanos, | ||
boolean cancellable, | ||
TaskId parentTaskId, | ||
Map<String, String> headers | ||
Map<String, String> headers, | ||
Map<String, Long> statsInfo | ||
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. We should instead use some |
||
) { | ||
this.taskId = taskId; | ||
this.type = type; | ||
|
@@ -106,6 +109,7 @@ public TaskInfo( | |
this.cancellable = cancellable; | ||
this.parentTaskId = parentTaskId; | ||
this.headers = headers; | ||
this.statsInfo = statsInfo; | ||
} | ||
|
||
/** | ||
|
@@ -126,6 +130,11 @@ public TaskInfo(StreamInput in) throws IOException { | |
} else { | ||
headers = Collections.emptyMap(); | ||
} | ||
if (in.getVersion().onOrAfter(LegacyESVersion.V_2_0_0)) { | ||
sruti1312 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
statsInfo = in.readMap(StreamInput::readString, StreamInput::readLong); | ||
} else { | ||
statsInfo = Collections.emptyMap(); | ||
} | ||
} | ||
|
||
@Override | ||
|
@@ -142,6 +151,9 @@ public void writeTo(StreamOutput out) throws IOException { | |
if (out.getVersion().onOrAfter(LegacyESVersion.V_6_2_0)) { | ||
out.writeMap(headers, StreamOutput::writeString, StreamOutput::writeString); | ||
} | ||
if (out.getVersion().onOrAfter(LegacyESVersion.V_2_0_0)) { | ||
sruti1312 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
out.writeMap(statsInfo, StreamOutput::writeString, StreamOutput::writeLong); | ||
} | ||
} | ||
|
||
public TaskId getTaskId() { | ||
|
@@ -207,6 +219,13 @@ public Map<String, String> getHeaders() { | |
return headers; | ||
} | ||
|
||
/** | ||
* Returns the tasks stats information | ||
*/ | ||
public Map<String, Long> getStatsInfo() { | ||
return statsInfo; | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
builder.field("node", taskId.getNodeId()); | ||
|
@@ -233,6 +252,13 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws | |
builder.field(attribute.getKey(), attribute.getValue()); | ||
} | ||
builder.endObject(); | ||
if (statsInfo != null) { | ||
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. In what case |
||
builder.startObject("stats_info"); | ||
for (Map.Entry<String, Long> attribute : statsInfo.entrySet()) { | ||
builder.field(attribute.getKey(), attribute.getValue()); | ||
} | ||
builder.endObject(); | ||
} | ||
return builder; | ||
} | ||
|
||
|
@@ -257,9 +283,27 @@ public static TaskInfo fromXContent(XContentParser parser) { | |
// This might happen if we are reading an old version of task info | ||
headers = Collections.emptyMap(); | ||
} | ||
@SuppressWarnings("unchecked") | ||
Map<String, Long> statsInfo = (Map<String, Long>) a[i++]; | ||
if (statsInfo == null) { | ||
// This might happen if we are reading an old version of task info or if stats information is not present | ||
statsInfo = Collections.emptyMap(); | ||
} | ||
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, | ||
parentTaskId, | ||
headers, | ||
statsInfo | ||
); | ||
}); | ||
static { | ||
// Note for the future: this has to be backwards and forwards compatible with all changes to the task storage format | ||
|
@@ -275,6 +319,7 @@ public static TaskInfo fromXContent(XContentParser parser) { | |
PARSER.declareBoolean(constructorArg(), new ParseField("cancellable")); | ||
PARSER.declareString(optionalConstructorArg(), new ParseField("parent_task_id")); | ||
PARSER.declareObject(optionalConstructorArg(), (p, c) -> p.mapStrings(), new ParseField("headers")); | ||
PARSER.declareObject(optionalConstructorArg(), (p, c) -> p.map(), new ParseField("stats_info")); | ||
} | ||
|
||
@Override | ||
|
@@ -298,11 +343,24 @@ public boolean equals(Object obj) { | |
&& Objects.equals(parentTaskId, other.parentTaskId) | ||
&& Objects.equals(cancellable, other.cancellable) | ||
&& Objects.equals(status, other.status) | ||
&& Objects.equals(headers, other.headers); | ||
&& Objects.equals(headers, other.headers) | ||
&& Objects.equals(statsInfo, other.statsInfo); | ||
} | ||
|
||
@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, | ||
status, | ||
headers, | ||
statsInfo | ||
); | ||
} | ||
} |
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 think we should use a request parameter (similar to
detailed
flag) to control if task API will return thestatus_info
in results or not. This will help to avoid breaking the backward compatibility where old client are accessing the clusterThere 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.
@dblock : When a new field is added in any REST API response object, will that break backward compatibility from client perspective ? Or adding a new field is fine and client doesn't perform any strict schema validation on response object ? Based on that info we can decide if a new parameter is needed to control the response payload with new field or not.
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 think new field are ok, @nknize can you confirm please?