karaf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r1055946 - in /karaf/branches/karaf-2.1.x: main/src/main/java/org/apache/karaf/main/Main.java main/src/main/java/org/apache/karaf/main/ShutdownCallback.java shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/Main.java
Date Thu, 06 Jan 2011 17:25:12 GMT
Author: gnodet
Date: Thu Jan  6 17:25:12 2011
New Revision: 1055946

URL: http://svn.apache.org/viewvc?rev=1055946&view=rev
Log:
[KARAF-327] Clean up graceful shutdown, make sure the wrapper is informed if the framework
is exited through osgi:shutdown

Modified:
    karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/Main.java
    karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/ShutdownCallback.java
    karaf/branches/karaf-2.1.x/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/Main.java

Modified: karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/Main.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/Main.java?rev=1055946&r1=1055945&r2=1055946&view=diff
==============================================================================
--- karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/Main.java (original)
+++ karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/Main.java Thu Jan
 6 17:25:12 2011
@@ -33,13 +33,11 @@ import java.security.Security;
 import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.lang.reflect.Method;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.ServiceReference;
@@ -148,6 +146,8 @@ public class Main {
     
     public static final String KARAF_FRAMEWORK = "karaf.framework";
 
+    public static final String KARAF_SHUTDOWN_TIMEOUT = "karaf.shutdown.timeout";
+
     public static final String KARAF_SHUTDOWN_PORT = "karaf.shutdown.port";
 
     public static final String KARAF_SHUTDOWN_HOST = "karaf.shutdown.host";
@@ -178,13 +178,18 @@ public class Main {
     private int defaultStartLevel = 100;
     private int lockStartLevel = 1;
     private int lockDelay = 1000;
+    private int shutdownTimeout = 5 * 60 * 1000;
     private boolean exiting = false;
-    private boolean cmProcessed;
+    private ShutdownCallback shutdownCallback;
 
     public Main(String[] args) {
         this.args = args;
     }
 
+    public void setShutdownCallback(ShutdownCallback shutdownCallback) {
+        this.shutdownCallback = shutdownCallback;
+    }
+
     public void launch() throws Exception {
         karafHome = Utils.getKarafHome();
         karafBase = Utils.getKarafDirectory(Main.PROP_KARAF_BASE, Main.ENV_KARAF_BASE, karafHome,
false, true);
@@ -231,6 +236,7 @@ public class Main {
         lockStartLevel = Integer.parseInt(configProps.getProperty(PROPERTY_LOCK_LEVEL, Integer.toString(lockStartLevel)));
         lockDelay = Integer.parseInt(configProps.getProperty(PROPERTY_LOCK_DELAY, Integer.toString(lockDelay)));
         configProps.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, Integer.toString(lockStartLevel));
+        shutdownTimeout = Integer.parseInt(configProps.getProperty(KARAF_SHUTDOWN_TIMEOUT,
Integer.toString(shutdownTimeout)));
         // Start up the OSGI framework
 
         InputStream is = classLoader.getResourceAsStream("META-INF/services/" + FrameworkFactory.class.getName());
@@ -249,52 +255,48 @@ public class Main {
         }.start();
     }
 
-    public void destroy(boolean await) throws Exception {
-		destroy(await, 0, null);
-	}
+    public void awaitShutdown() throws Exception {
+        while (true) {
+            FrameworkEvent event = framework.waitForStop(0);
+            if (event.getType() != FrameworkEvent.STOPPED_UPDATE) {
+                return;
+            }
+        }
+    }
 
-	public void destroy(boolean await, int timeout, ShutdownCallback callback) throws Exception
{
+	public boolean destroy() throws Exception {
         if (framework == null) {
-            return;
+            return true;
         }
         try {
-            if (await) {
-                while (true) {
-                	FrameworkEvent event;
-	                if (callback != null) {
-	                	callback.waitingForShutdown();
-	                	event = framework.waitForStop(timeout);
-	                	//do the stoping in an extra thread
-	                	Runnable stopper = new Runnable() {
-							
-							public void run() {
-								try {
-									
-									framework.stop();
-								} catch (BundleException e) {
-									System.err.println("Exception while stoping framework: " + e);
-								}
-							}
-						};
-	                	Thread t = new Thread(stopper);
-	                	t.start();
-	                	while (t.getState() != Thread.State.TERMINATED && event.getType()
== FrameworkEvent.WAIT_TIMEDOUT) {
-	                		callback.waitingForShutdown();
-	                		event = framework.waitForStop(timeout);
-	                	} 
-	                	break;
-                	} else {
-                		event = framework.waitForStop(0);
-                	}
-                	if (event.getType() != FrameworkEvent.STOPPED_UPDATE) {
-                        break;
-                    }
-                }
+            int step = 5000;
+
+            // Notify the callback asap
+            if (shutdownCallback != null) {
+                shutdownCallback.waitingForShutdown(step);
             }
+
+            // Stop the framework in case it's still active
             exiting = true;
             if (framework.getState() == Bundle.ACTIVE) {
                 framework.stop();
             }
+
+            int timeout = shutdownTimeout;
+            if (shutdownTimeout <= 0) {
+                timeout = Integer.MAX_VALUE;
+            }
+            while (timeout > 0) {
+                timeout -= step;
+                if (shutdownCallback != null) {
+                    shutdownCallback.waitingForShutdown(step * 2);
+                }
+                FrameworkEvent event = framework.waitForStop(step);
+                if (event.getType() != FrameworkEvent.WAIT_TIMEDOUT) {
+                    return true;
+                }
+            }
+            return false;
         } finally {
             unlock();
         }
@@ -396,8 +398,17 @@ public class Main {
                 ex.printStackTrace();
             }
             try {
-                main.destroy(true);
+                main.awaitShutdown();
+                boolean stopped = main.destroy();
                 restart = Boolean.getBoolean("karaf.restart");
+                if (!stopped) {
+                    if (restart) {
+                        System.err.println("Timeout waiting for framework to stop.  Restarting
now.");
+                    } else {
+                        System.err.println("Timeout waiting for framework to stop.  Exiting
VM.");
+                        main.setExitCode(-3);
+                    }
+                }
             } catch (Throwable ex) {
                 main.setExitCode(-2);
                 System.err.println("Error occured shutting down framework: " + ex);

Modified: karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/ShutdownCallback.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/ShutdownCallback.java?rev=1055946&r1=1055945&r2=1055946&view=diff
==============================================================================
--- karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/ShutdownCallback.java
(original)
+++ karaf/branches/karaf-2.1.x/main/src/main/java/org/apache/karaf/main/ShutdownCallback.java
Thu Jan  6 17:25:12 2011
@@ -32,6 +32,6 @@ public interface ShutdownCallback {
 	 * The callback method invoked to inform anyone listening that the 
 	 * Main class is still waiting for the completion of the shutdown. 
 	 */
-	void waitingForShutdown();
-	
+	void waitingForShutdown(int delay);
+
 }

Modified: karaf/branches/karaf-2.1.x/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/Main.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.1.x/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/Main.java?rev=1055946&r1=1055945&r2=1055946&view=diff
==============================================================================
--- karaf/branches/karaf-2.1.x/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/Main.java
(original)
+++ karaf/branches/karaf-2.1.x/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/Main.java
Thu Jan  6 17:25:12 2011
@@ -23,11 +23,10 @@ import org.tanukisoftware.wrapper.Wrappe
 /**
  * Java Service Wrapper Main class
  */
-public class Main implements WrapperListener, ShutdownCallback {
+public class Main extends Thread implements WrapperListener, ShutdownCallback {
 
-    private static final int TIMEOUT = 1000; //wainting timeout for a second should be enough
-	private static final int TIMEOUT_OFFSET = 500; // the offset for the wrapper, to leave us
some time to breath
-	private org.apache.karaf.main.Main main;
+   	private org.apache.karaf.main.Main main;
+    private volatile boolean destroying;
 
     /*---------------------------------------------------------------
      * Constructors
@@ -57,6 +56,8 @@ public class Main implements WrapperList
         try
         {
             main.launch();
+            main.setShutdownCallback(this);
+            start();
             return null;
         }
         catch (Throwable ex)
@@ -65,7 +66,17 @@ public class Main implements WrapperList
             ex.printStackTrace();
             return -1;
         }
+    }
 
+    public void run() {
+        try {
+            main.awaitShutdown();
+            if (!destroying) {
+                WrapperManager.stop(main.getExitCode());
+            }
+        } catch (Exception e) {
+            // Ignore
+        }
     }
 
     /**
@@ -88,7 +99,8 @@ public class Main implements WrapperList
     {
         try
         {
-            main.destroy(true, TIMEOUT, this);
+            destroying = true;
+            main.destroy();
         }
         catch (Throwable ex)
         {
@@ -97,15 +109,15 @@ public class Main implements WrapperList
             return -2;
         }
 
-        return exitCode;
+        return main.getExitCode();
     }
     
     /**
      * Call-back method is called by the @{link org.apache.karaf.main.Main} for Signaling

      * that the stopping process is in progress and the wrapper doesn't kill the JVM.  
      */
-    public void waitingForShutdown() {
-    	WrapperManager.signalStopping(TIMEOUT + TIMEOUT_OFFSET);
+    public void waitingForShutdown(int delay) {
+    	WrapperManager.signalStopping(delay);
     }
 
     /**



Mime
View raw message