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

Implementation_of_Error_Metric_for_Rest_Actions #4567

Closed
wants to merge 5 commits into from

Conversation

vzez
Copy link

@vzez vzez commented Sep 21, 2022

Description

Complete implementation of issue: #4401

Issues Resolved

#4401

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed per the DCO using --signoff
  • Commit changes are listed out in CHANGELOG.md file (See: Changelog)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@vzez vzez requested review from a team and reta as code owners September 21, 2022 20:23
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Author Name <vjg@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@@ -79,6 +81,7 @@ public NodesStatsRequest(StreamInput in) throws IOException {
optionallyAddMetric(in.readBoolean(), Metric.ADAPTIVE_SELECTION.metricName());
} else {
requestedMetrics.addAll(in.readStringList());
restActionsFilters.addAll(in.readStringList());
Copy link
Member

Choose a reason for hiding this comment

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

What happens if no filters are provided?

Copy link
Author

Choose a reason for hiding this comment

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

if filters not provided, we'll get status count for all rest rest actions having count > 0

* @opensearch.internal
*/
public class RestActionsStats implements Writeable, ToXContentFragment {
private Map<String, Map<Integer, Integer>> restActionsStatusCount;
Copy link
Member

@mgodwan mgodwan Oct 9, 2022

Choose a reason for hiding this comment

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

Can we use Long here for the count?

Copy link
Author

Choose a reason for hiding this comment

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

I think status count won't go beyond INT range, so making it LONG, will cause memory wastage.

*/
public class RestActionsStats implements Writeable, ToXContentFragment {
private Map<String, Map<Integer, Integer>> restActionsStatusCount;
private Map<Integer, Integer> restActionsStatusTotalCount;
Copy link
Member

Choose a reason for hiding this comment

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

  1. Can you add documentation for the fields here?
  2. Is the key supposed to denote the status code?

Copy link
Author

Choose a reason for hiding this comment

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

  1. What sort of doc is req here? could you please explain.
  2. For Map @Line30 , yes, the status code is the Key. For Map @line29 "action name" is the key.

@mgodwan
Copy link
Member

mgodwan commented Oct 9, 2022

Could you help with the sample request and response structure for this?

*
* @opensearch.internal
*/
public class RestActionsService {
Copy link
Member

Choose a reason for hiding this comment

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

Can we see if a name like RestActionsStatsService is better suited for this, since this only deals with stats for the rest actions and no other operations?

Copy link
Author

Choose a reason for hiding this comment

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

Indeed, "RestActionsStatsService" better suits here and gives a clear info about class as well.
I came up with another one also -"RestActionsStatsCountService" , will it be ok?

Comment on lines 39 to 48
private Map<Integer, Integer> getRestActionsStatusTotalCount(Map<String, Map<Integer, Integer>> mapHandlerStatusCount) {
final Map<Integer, Integer> totalStatusCount = new TreeMap<>();
mapHandlerStatusCount.entrySet().stream().flatMap(entry -> entry.getValue().entrySet().stream()).forEach(entry -> {
Integer count = totalStatusCount.get(entry.getKey());
if (null == count) count = 0;
count += entry.getValue();
totalStatusCount.put(entry.getKey(), count);
});
return totalStatusCount;
}
Copy link
Member

Choose a reason for hiding this comment

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

Please ensure to have unit tests tests for null values

Copy link
Author

Choose a reason for hiding this comment

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

I'll cross check, if not added, I'll add them.

Comment on lines 64 to 68
private void increment(Map<Integer, Integer> statusCount, int status) {
Integer count = statusCount.get(status);
if (null == count) count = 0;
statusCount.put(status, ++count);
}
Copy link
Member

Choose a reason for hiding this comment

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

We need to make it thread safe. Can we use AtomicLong here to ensure we don't skip any count?

Copy link
Member

Choose a reason for hiding this comment

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

Also, please see if we can tests to verify thread safety across operations

Copy link
Author

Choose a reason for hiding this comment

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

Rather using AtomicLong , we can make the Map thread-safe?

if (handler.getName() == null) {
throw new IllegalArgumentException("handler of type [" + handler.getClass().getName() + "] does not have a name");
}
handlers.putIfAbsent(handler.getName(), new TreeMap<>());
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the inner map be thread safe as well?

if (handler.getName() == null) {
throw new IllegalArgumentException("handler of type [" + handler.getClass().getName() + "] does not have a name");
}
handlers.putIfAbsent(handler.getName(), new TreeMap<>());
Copy link
Member

Choose a reason for hiding this comment

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

Fail if already present as well?

Copy link
Author

Choose a reason for hiding this comment

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

No, putIfAbsent only puts value if no entry exists for the key and returns null, if key is already there it doesn't replace exiting value but returns existing value.
ex:
map.putIfAbsent("exist", "no"); --- returns null
map.putIfAbsent("exist", "yes"); --- returns "no"
there is no error or exception

Comment on lines 591 to 594
if (restHandler instanceof BaseRestHandler) restActionsService.putStatus(
((BaseRestHandler) restHandler).getName(),
response.status()
);
Copy link
Member

Choose a reason for hiding this comment

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

[Nit] Can we re-format this snippet to be aligned with the convention followed in the repository?

Copy link
Author

Choose a reason for hiding this comment

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

I already formatted code using ./gradlew spotlessApply.
I guess had the code not formatted using above command, it couldn't be pushed.

Comment on lines +198 to +200
if (metrics.contains("rest_actions") && request.hasParam("rest_actions_filters")) {
nodesStatsRequest.addRestActionsFilters(request.paramAsStringArray("rest_actions_filters", null));
} else if (request.hasParam("rest_actions_filters")) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need validations on the provided values for rest_actions_filters as well?

Copy link
Author

Choose a reason for hiding this comment

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

I did have thoughts about it while coding but the thing is we need to maintain the list of all rest actions and whenever a new rest action would be introduced, it must be added to that list. So I think it's un-necessary. As per current implementation if filter contain invalid action name it won't be returned as response.

Or we have to use RestActionsService (class in which all handlers are being registered) ref here, again it creates un-necessary dependency which I think is not a good design.

@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

Signed-off-by: Author Name <vjg@amazon.com>
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@vzez vzez closed this Oct 14, 2022
@vzez vzez reopened this Oct 14, 2022
@github-actions
Copy link
Contributor

Gradle Check (Jenkins) Run Completed with:

@vzez
Copy link
Author

vzez commented Nov 28, 2022

Closing this PR , new PR raised by Prabhat #5334

@vzez vzez closed this Nov 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants