You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/07/29 17:35:30 UTC
[2/4] incubator-brooklyn git commit: Wait apps to stop before
shutting down.
Wait apps to stop before shutting down.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/79a1847a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/79a1847a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/79a1847a
Branch: refs/heads/master
Commit: 79a1847a6ca31a1c18569782d73cb8c4662e819a
Parents: b83ef4d
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Jul 24 23:12:22 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Jul 29 17:04:22 2015 +0300
----------------------------------------------------------------------
.../brooklyn/rest/resources/ServerResource.java | 55 ++++++++++++++++++--
1 file changed, 50 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/79a1847a/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java
index a4e9800..24e0e05 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java
@@ -43,9 +43,11 @@ import com.google.common.collect.FluentIterable;
import brooklyn.BrooklynVersion;
import brooklyn.config.ConfigKey;
import brooklyn.entity.Application;
+import brooklyn.entity.basic.Attributes;
import brooklyn.entity.basic.ConfigKeys;
import brooklyn.entity.basic.Entities;
import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.basic.Lifecycle;
import brooklyn.entity.basic.StartableApplication;
import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
import brooklyn.entity.rebind.persister.FileBasedObjectStore;
@@ -136,6 +138,7 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
@Override
public void run() {
boolean terminateTried = false;
+ ManagementContext mgmt = mgmt();
try {
if (stopAppsFirst) {
CountdownTimer shutdownTimeoutTimer = null;
@@ -143,22 +146,50 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
shutdownTimeoutTimer = shutdownTimeout.countdownTimer();
}
+ log.debug("Stopping applications");
List<Task<?>> stoppers = new ArrayList<Task<?>>();
- for (Application app: mgmt().getApplications()) {
- if (app instanceof StartableApplication)
+ int allStoppableApps = 0;
+ for (Application app: mgmt.getApplications()) {
+ allStoppableApps++;
+ Lifecycle appState = app.getAttribute(Attributes.SERVICE_STATE_ACTUAL);
+ if (app instanceof StartableApplication &&
+ // Don't try to stop an already stopping app. Subsequent stops will complete faster
+ // cancelling the first stop task.
+ appState != Lifecycle.STOPPING) {
stoppers.add(Entities.invokeEffector((EntityLocal)app, app, StartableApplication.STOP));
+ } else {
+ log.debug("App " + app + " is already stopping, will not stop second time. Will wait for original stop to complete.");
+ }
}
+ log.debug("Waiting for " + allStoppableApps + " apps to stop, of which " + stoppers.size() + " stopped explicitly.");
for (Task<?> t: stoppers) {
if (!waitAppShutdown(shutdownTimeoutTimer, t)) {
//app stop error
hasAppErrorsOrTimeout.set(true);
}
}
+
+ // Wait for apps which were already stopping when we tried to shut down.
+ if (hasStoppableApps(mgmt)) {
+ log.debug("Apps are still stopping, wait for proper unmanage.");
+ while (hasStoppableApps(mgmt) && (shutdownTimeoutTimer == null || !shutdownTimeoutTimer.isExpired())) {
+ Duration wait;
+ if (shutdownTimeoutTimer != null) {
+ wait = Duration.min(shutdownTimeoutTimer.getDurationRemaining(), Duration.ONE_SECOND);
+ } else {
+ wait = Duration.ONE_SECOND;
+ }
+ Time.sleep(wait);
+ }
+ if (hasStoppableApps(mgmt)) {
+ hasAppErrorsOrTimeout.set(true);
+ }
+ }
}
terminateTried = true;
- ((ManagementContextInternal)mgmt()).terminate();
+ ((ManagementContextInternal)mgmt).terminate();
} catch (Throwable e) {
Throwable interesting = Exceptions.getFirstInteresting(e);
@@ -176,7 +207,7 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
hasAppErrorsOrTimeout.set(true);
if (!terminateTried) {
- ((ManagementContextInternal)mgmt()).terminate();
+ ((ManagementContextInternal)mgmt).terminate();
}
} finally {
@@ -201,6 +232,19 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
}
}
+ private boolean hasStoppableApps(ManagementContext mgmt) {
+ for (Application app : mgmt.getApplications()) {
+ if (app instanceof StartableApplication) {
+ Lifecycle state = app.getAttribute(Attributes.SERVICE_STATE_ACTUAL);
+ if (state != Lifecycle.STOPPING && state != Lifecycle.STOPPED) {
+ log.warn("Shutting down, expecting all apps to be in stopping state, but found application " + app + " to be in state " + state + ". Just started?");
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
private void complete() {
synchronized (completed) {
completed.set(true);
@@ -214,6 +258,7 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
if (shutdownTimeoutTimer != null) {
waitInterval = Duration.of(SHUTDOWN_TIMEOUT_CHECK_INTERVAL, TimeUnit.MILLISECONDS);
}
+ // waitInterval == null - blocks indefinitely
while(!t.blockUntilEnded(waitInterval)) {
if (shutdownTimeoutTimer.isExpired()) {
log.warn("Timeout while waiting for applications to stop at "+t+".\n"+t.getStatusDetail(true));
@@ -237,7 +282,7 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
//then better wait until the 'completed' flag is set, rather than timing out
//at just about the same time (i.e. always wait for the shutdownTimeout in this case).
//This will prevent undefined behaviour where either one of shutdownTimeout or requestTimeout
- //will be first to expire and the error flag won't be set predicably, it will
+ //will be first to expire and the error flag won't be set predictably, it will
//toggle depending on which expires first.
//Note: shutdownTimeout is checked at SHUTDOWN_TIMEOUT_CHECK_INTERVAL interval, meaning it is
//practically rounded up to the nearest SHUTDOWN_TIMEOUT_CHECK_INTERVAL.