jiajunwang commented on a change in pull request #1187:
URL: https://github.com/apache/helix/pull/1187#discussion_r465397897
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedStateComputationStage.java
##########
@@ -86,6 +86,9 @@ private void updateCustomizedStates(String instanceName,
String customizedStateT
customizedStateOutput
.setCustomizedState(customizedStateType, resourceName,
partition, instanceName,
customizedState.getState(partitionName));
+ customizedStateOutput
+ .setStartTime(customizedStateType, resourceName, partition,
instanceName,
+ String.valueOf(customizedState.getStartTime(partitionName)));
Review comment:
Can you process the long type inside the method? Converting the type in
the caller is not clean. If you have multiple callers, then you will need to
convert every time.
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedStateComputationStage.java
##########
@@ -86,6 +86,9 @@ private void updateCustomizedStates(String instanceName,
String customizedStateT
customizedStateOutput
.setCustomizedState(customizedStateType, resourceName,
partition, instanceName,
customizedState.getState(partitionName));
+ customizedStateOutput
Review comment:
Will it be simpler if you set the start time inside
setCustomizedState()? Are there any other cases that you want to update the
state but don't touch the start time?
This will help to reduce duplicate code.
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedStateOutput.java
##########
@@ -24,32 +24,58 @@
import java.util.Map;
import java.util.Set;
+import org.apache.helix.model.CustomizedState;
import org.apache.helix.model.Partition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CustomizedStateOutput {
+ private static final Logger LOG =
LoggerFactory.getLogger(CustomizedStateOutput.class);
+
// stateType -> (resourceName -> (Partition -> (instanceName ->
customizedState)))
private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_customizedStateMap;
+ // stateType -> (resourceName -> (Partition -> (instanceName -> startTime)))
+ private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_startTimeMap;
public CustomizedStateOutput() {
_customizedStateMap = new HashMap<>();
+ _startTimeMap = new HashMap<>();
}
public void setCustomizedState(String stateType, String resourceName,
Partition partition,
String instanceName, String state) {
- if (!_customizedStateMap.containsKey(stateType)) {
- _customizedStateMap
- .put(stateType, new HashMap<String, Map<Partition, Map<String,
String>>>());
- }
- if (!_customizedStateMap.get(stateType).containsKey(resourceName)) {
- _customizedStateMap.get(stateType)
- .put(resourceName, new HashMap<Partition, Map<String, String>>());
- }
- if
(!_customizedStateMap.get(stateType).get(resourceName).containsKey(partition)) {
- _customizedStateMap.get(stateType).get(resourceName)
- .put(partition, new HashMap<String, String>());
+
setCustomizedStateProperty(CustomizedState.CustomizedStateProperty.CURRENT_STATE,
stateType,
+ resourceName, partition, instanceName, state);
+ }
+
+ public void setStartTime(String stateType, String resourceName, Partition
partition,
+ String instanceName, String state) {
Review comment:
It is called set start time, but you put a "state" in the parameter. It
looks strange.
##########
File path: helix-core/src/main/java/org/apache/helix/InstanceType.java
##########
@@ -37,7 +37,8 @@
MonitorDomainNames.ClusterStatus.name(),
MonitorDomainNames.HelixZkClient.name(),
MonitorDomainNames.HelixCallback.name(),
- MonitorDomainNames.Rebalancer.name()
+ MonitorDomainNames.Rebalancer.name(),
+ MonitorDomainNames.CustomizedView.name()
Review comment:
CustomizedView -> AggregatedView ? In this case, we can transfer EV TEV
metrics to this domain in the future.
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedStateOutput.java
##########
@@ -24,32 +24,58 @@
import java.util.Map;
import java.util.Set;
+import org.apache.helix.model.CustomizedState;
import org.apache.helix.model.Partition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CustomizedStateOutput {
+ private static final Logger LOG =
LoggerFactory.getLogger(CustomizedStateOutput.class);
+
// stateType -> (resourceName -> (Partition -> (instanceName ->
customizedState)))
private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_customizedStateMap;
Review comment:
I know we are doing this style (separate maps for different fields)
everywhere, but I am thinking if we can make it better. Either using the Pair
or make a private class will definitely help to simplify the code here.
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedViewAggregationStage.java
##########
@@ -152,6 +163,33 @@ private void computeCustomizedStateView(final Resource
resource, final String st
if (curCustomizedView == null ||
!curCustomizedView.getRecord().equals(view.getRecord())) {
// Add customized view to the list which will be written to ZK later.
updatedCustomizedViews.add(view);
+ updatedStartTimestamps.put(resourceName,
+ customizedStateOutput.getResourceStartTimeMap(stateType,
resourceName));
}
}
+
+ private CustomizedViewMonitor getOrCreateMonitor(ClusterEvent event) throws
JMException {
Review comment:
Once we put this map into the cache object, concurrent control is
necessary for this method.
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedViewAggregationStage.java
##########
@@ -35,17 +37,20 @@
import org.apache.helix.controller.LogUtil;
import
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.pipeline.AbstractAsyncBaseStage;
+import org.apache.helix.controller.pipeline.AbstractBaseStage;
import org.apache.helix.controller.pipeline.AsyncWorkerType;
import org.apache.helix.controller.pipeline.StageException;
import org.apache.helix.model.CustomizedView;
import org.apache.helix.model.Partition;
import org.apache.helix.model.Resource;
+import org.apache.helix.monitoring.mbeans.CustomizedViewMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CustomizedViewAggregationStage extends AbstractAsyncBaseStage {
private static Logger LOG =
LoggerFactory.getLogger(CustomizedViewAggregationStage.class);
+ private Map<String, CustomizedViewMonitor> _monitors = new HashMap<>();
Review comment:
I think we shall make stage object stateless. So this monitor map shall
be in the cache.
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedStateOutput.java
##########
@@ -24,32 +24,58 @@
import java.util.Map;
import java.util.Set;
+import org.apache.helix.model.CustomizedState;
import org.apache.helix.model.Partition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CustomizedStateOutput {
+ private static final Logger LOG =
LoggerFactory.getLogger(CustomizedStateOutput.class);
+
// stateType -> (resourceName -> (Partition -> (instanceName ->
customizedState)))
private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_customizedStateMap;
+ // stateType -> (resourceName -> (Partition -> (instanceName -> startTime)))
+ private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_startTimeMap;
public CustomizedStateOutput() {
_customizedStateMap = new HashMap<>();
+ _startTimeMap = new HashMap<>();
}
public void setCustomizedState(String stateType, String resourceName,
Partition partition,
String instanceName, String state) {
- if (!_customizedStateMap.containsKey(stateType)) {
- _customizedStateMap
- .put(stateType, new HashMap<String, Map<Partition, Map<String,
String>>>());
- }
- if (!_customizedStateMap.get(stateType).containsKey(resourceName)) {
- _customizedStateMap.get(stateType)
- .put(resourceName, new HashMap<Partition, Map<String, String>>());
- }
- if
(!_customizedStateMap.get(stateType).get(resourceName).containsKey(partition)) {
- _customizedStateMap.get(stateType).get(resourceName)
- .put(partition, new HashMap<String, String>());
+
setCustomizedStateProperty(CustomizedState.CustomizedStateProperty.CURRENT_STATE,
stateType,
+ resourceName, partition, instanceName, state);
+ }
+
+ public void setStartTime(String stateType, String resourceName, Partition
partition,
+ String instanceName, String state) {
+
setCustomizedStateProperty(CustomizedState.CustomizedStateProperty.START_TIME,
stateType,
+ resourceName, partition, instanceName, state);
+ }
+
+ private void
setCustomizedStateProperty(CustomizedState.CustomizedStateProperty propertyName,
+ String stateType, String resourceName, Partition partition, String
instanceName,
+ String state) {
+ Map<String, Map<String, Map<Partition, Map<String, String>>>> mapToUpdate;
+ switch (propertyName) {
Review comment:
These are duplicate logic with the switch block in
getCustomizedStateProperty().
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedStateOutput.java
##########
@@ -24,32 +24,58 @@
import java.util.Map;
import java.util.Set;
+import org.apache.helix.model.CustomizedState;
import org.apache.helix.model.Partition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CustomizedStateOutput {
+ private static final Logger LOG =
LoggerFactory.getLogger(CustomizedStateOutput.class);
+
// stateType -> (resourceName -> (Partition -> (instanceName ->
customizedState)))
private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_customizedStateMap;
+ // stateType -> (resourceName -> (Partition -> (instanceName -> startTime)))
+ private final Map<String, Map<String, Map<Partition, Map<String, String>>>>
_startTimeMap;
Review comment:
Why not save the Long type for the startTime here?
##########
File path:
helix-core/src/main/java/org/apache/helix/controller/stages/CustomizedViewAggregationStage.java
##########
@@ -107,8 +114,11 @@ public void execute(final ClusterEvent event) throws
Exception {
}
// add/update customized-views from zk and cache
if (updatedCustomizedViews.size() > 0) {
- dataAccessor.setChildren(keys, updatedCustomizedViews);
+ boolean[] success = dataAccessor.setChildren(keys,
updatedCustomizedViews);
cache.updateCustomizedViews(stateType, updatedCustomizedViews);
+ asyncReportLatency(cache.getAsyncTasksThreadPool(),
getOrCreateMonitor(event),
+ new ArrayList<>(updatedCustomizedViews),
curCustomizedViewsCopy,
+ new HashMap<>(updatedStartTimestamps), success.clone(),
System.currentTimeMillis());
Review comment:
Do you really need to clone the success array?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]