[ASTERIXDB-2137][ING][API] Prevent REST API hang on stopped feeds
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
1. Due to the ActiveEventListener change, current implementation will
try to issue stats request to stopped feed and never get back. This is
fixed.
2. Now we only request stats for active feeds.
3. When feed stopped, the cached stats will be reinitialized. This is to
prevent users see the previous active stats after immediate start after
stop.
Change-Id: Ifd35ba0e61ac73086c6ba276e1f25a0cd094cf8c
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2085
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: abdullah alamoudi <bamousaa@gmail.com>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveStatsApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveStatsApiServlet.java
index 7e6d54b..a4889ce 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveStatsApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ActiveStatsApiServlet.java
@@ -76,8 +76,10 @@
}
long currentTime = System.currentTimeMillis();
for (int iter1 = 0; iter1 < listeners.length; iter1++) {
- resNode.putPOJO(listeners[iter1].getDisplayName(),
- constructNode(OBJECT_MAPPER, listeners[iter1], currentTime, expireTime));
+ if (listeners[iter1].isActive()) {
+ resNode.putPOJO(listeners[iter1].getDisplayName(),
+ constructNode(OBJECT_MAPPER, listeners[iter1], currentTime, expireTime));
+ }
}
// Construct Response
responseWriter.write(OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(resNode));
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/active/ActiveEntityEventsListener.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/active/ActiveEntityEventsListener.java
index 73d0840..e3c1fed 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/active/ActiveEntityEventsListener.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/active/ActiveEntityEventsListener.java
@@ -65,6 +65,7 @@
private static final ActiveEvent STATE_CHANGED = new ActiveEvent(null, Kind.STATE_CHANGED, null, null);
private static final EnumSet<ActivityState> TRANSITION_STATES = EnumSet.of(ActivityState.RESUMING,
ActivityState.STARTING, ActivityState.STOPPING, ActivityState.RECOVERING);
+ private static final String DEFAULT_ACTIVE_STATS = "{\"Stats\":\"N/A\"}";
// finals
protected final IClusterStateManager clusterStateManager;
protected final ActiveNotificationHandler handler;
@@ -113,7 +114,7 @@
this.statsTimestamp = -1;
this.isFetchingStats = false;
this.statsUpdatedEvent = new ActiveEvent(null, Kind.STATS_UPDATED, entityId, null);
- this.stats = "{\"Stats\":\"N/A\"}";
+ this.stats = DEFAULT_ACTIVE_STATS;
this.runtimeName = runtimeName;
this.locations = locations;
this.numRegistered = 0;
@@ -275,9 +276,12 @@
public void refreshStats(long timeout) throws HyracksDataException {
LOGGER.log(level, "refreshStats called");
synchronized (this) {
- if (state != ActivityState.RUNNING || isFetchingStats) {
- LOGGER.log(level,
- "returning immediately since state = " + state + " and fetchingStats = " + isFetchingStats);
+ if (state != ActivityState.RUNNING) {
+ LOGGER.log(level, "returning immediately since state = " + state);
+ notifySubscribers(statsUpdatedEvent);
+ return;
+ } else if (isFetchingStats) {
+ LOGGER.log(level, "returning immediately since fetchingStats = " + isFetchingStats);
return;
} else {
isFetchingStats = true;
@@ -426,6 +430,8 @@
} else {
throw new RuntimeDataException(ErrorCode.ACTIVE_ENTITY_CANNOT_BE_STOPPED, entityId, state);
}
+ this.stats = DEFAULT_ACTIVE_STATS;
+ notifySubscribers(statsUpdatedEvent);
}
public RecoveryTask getRecoveryTask() {