You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2016/04/21 19:17:12 UTC

[37/50] [abbrv] incubator-geode git commit: GEODE-1236 GEODE-1248: Fix gfsh sutdown call

GEODE-1236 GEODE-1248: Fix gfsh sutdown call

- This fixes two issues when using gfsh 'shutdown' command
- One is that the JVM can exit prematurely because all remaining threads
  are daemon threads. When coupled with network partition detection this
  can result in member departed events causing split brain scenarios -
  [GEODE-1236].
- The other issue is that when a member is starting up it may have
  synchronized on the CacheFactory class waiting on disk store recovery.
  This prevented gfsh shutdown to run as it would also try and
  synchronize on the CacheFactory and be blocked.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/ea97a536
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/ea97a536
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/ea97a536

Branch: refs/heads/feature/GEODE-17-2
Commit: ea97a536e9175f36c4bc8d69a89d079649d44f82
Parents: 8d4dfc2
Author: Jens Deppe <jd...@pivotal.io>
Authored: Tue Apr 19 12:42:58 2016 -0700
Committer: Jens Deppe <jd...@pivotal.io>
Committed: Wed Apr 20 13:52:32 2016 -0700

----------------------------------------------------------------------
 .../cli/functions/ShutDownFunction.java         | 52 ++++++++++++++------
 1 file changed, 36 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ea97a536/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/ShutDownFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/ShutDownFunction.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/ShutDownFunction.java
index 90b582b..27e3704 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/ShutDownFunction.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/ShutDownFunction.java
@@ -16,16 +16,18 @@
  */
 package com.gemstone.gemfire.management.internal.cli.functions;
 
-import org.apache.logging.log4j.Logger;
-
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.cache.execute.Function;
 import com.gemstone.gemfire.cache.execute.FunctionContext;
 import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
 import com.gemstone.gemfire.internal.InternalEntity;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.tcp.ConnectionTable;
+import org.apache.logging.log4j.Logger;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 /**
  * 
@@ -43,21 +45,39 @@ public class ShutDownFunction implements Function, InternalEntity {
   @Override
   public void execute(FunctionContext context) {
     try {
-      Cache cache = CacheFactory.getAnyInstance();
-      String memberName = cache.getDistributedSystem().getDistributedMember().getId();
-      cache.getLogger().info("Received GFSH shutdown. Shutting down member " + memberName);
-      final InternalDistributedSystem system = ((InternalDistributedSystem) cache.getDistributedSystem());
-
-      if (system.isConnected()) {
-        ConnectionTable.threadWantsSharedResources();
-        if (system.isConnected()) {
-          system.disconnect();
-        }
+      final InternalDistributedSystem system = InternalDistributedSystem.getConnectedInstance();
+      if (system == null) {
+        return;
       }
-      
+      String memberName = system.getDistributedMember().getId();
+      logger.info("Received GFSH shutdown. Shutting down member " + memberName);
+
+      disconnectInNonDaemonThread(system);
+
       context.getResultSender().lastResult("SUCCESS: succeeded in shutting down " + memberName);
     } catch (Exception ex) {
-      context.getResultSender().lastResult("FAILURE: failed in shutting down " +ex.getMessage());
+      logger.warn("Error during shutdown", ex);
+      context.getResultSender().lastResult("FAILURE: failed in shutting down " + ex.getMessage());
+    }
+  }
+
+  /*
+   * The shutdown is performed in a separate, non-daemon thread so that the JVM does not shut down
+   * prematurely before the full process has completed.
+   */
+  private void disconnectInNonDaemonThread(final InternalDistributedSystem ids)
+      throws InterruptedException, ExecutionException {
+    ExecutorService exec = Executors.newSingleThreadExecutor();
+    Future future = exec.submit(() -> {
+      ConnectionTable.threadWantsSharedResources();
+      if (ids.isConnected()) {
+        ids.disconnect();
+      }
+    });
+    try {
+      future.get();
+    } finally {
+      exec.shutdown();
     }
   }