You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by mi...@apache.org on 2014/03/23 04:12:57 UTC

svn commit: r1580436 - in /zookeeper/trunk: ./ src/java/main/org/apache/zookeeper/ src/java/main/org/apache/zookeeper/server/ src/java/main/org/apache/zookeeper/server/quorum/ src/java/test/config/ src/java/test/org/apache/zookeeper/server/

Author: michim
Date: Sun Mar 23 03:12:56 2014
New Revision: 1580436

URL: http://svn.apache.org/r1580436
Log:
ZOOKEEPER-602. log all exceptions not caught by ZK threads (Rakesh R via michim)

Added:
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperThread.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/server/ZooKeeperThreadTest.java
Modified:
    zookeeper/trunk/CHANGES.txt
    zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NIOServerCnxnFactory.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SessionTrackerImpl.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SyncRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/WorkerService.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/AuthFastLeaderElection.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FastLeaderElection.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ObserverRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ReadOnlyRequestProcessor.java
    zookeeper/trunk/src/java/test/config/findbugsExcludeFile.xml

Modified: zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/trunk/CHANGES.txt?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/CHANGES.txt (original)
+++ zookeeper/trunk/CHANGES.txt Sun Mar 23 03:12:56 2014
@@ -800,6 +800,9 @@ IMPROVEMENTS:
   ZOOKEEPER-1796. Move common code from {Follower, Observer}ZooKeeperServer into
   LearnerZooKeeperServer (Raul Gutierrez Segales via michim)
 
+  ZOOKEEPER-602. log all exceptions not caught by ZK threads (Rakesh R via
+  michim)
+
 headers
 
 Release 3.4.0 - 

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java Sun Mar 23 03:12:56 2014
@@ -80,6 +80,7 @@ import org.apache.zookeeper.proto.SetDat
 import org.apache.zookeeper.proto.SetWatches;
 import org.apache.zookeeper.proto.WatcherEvent;
 import org.apache.zookeeper.server.ByteBufferInputStream;
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.ZooTrace;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -418,13 +419,6 @@ public class ClientCnxn {
 
     private Object eventOfDeath = new Object();
 
-    private final static UncaughtExceptionHandler uncaughtExceptionHandler = new UncaughtExceptionHandler() {
-        @Override
-        public void uncaughtException(Thread t, Throwable e) {
-            LOG.error("from " + t.getName(), e);
-        }
-    };
-
     private static class WatcherSetEventPair {
         private final Set<Watcher> watchers;
         private final WatchedEvent event;
@@ -446,7 +440,7 @@ public class ClientCnxn {
         return name + suffix;
     }
 
-    class EventThread extends Thread {
+    class EventThread extends ZooKeeperThread {
         private final LinkedBlockingQueue<Object> waitingEvents =
             new LinkedBlockingQueue<Object>();
 
@@ -461,7 +455,6 @@ public class ClientCnxn {
 
         EventThread() {
             super(makeThreadName("-EventThread"));
-            setUncaughtExceptionHandler(uncaughtExceptionHandler);
             setDaemon(true);
         }
 
@@ -817,7 +810,7 @@ public class ClientCnxn {
      * This class services the outgoing request queue and generates the heart
      * beats. It also spawns the ReadThread.
      */
-    class SendThread extends Thread {
+    class SendThread extends ZooKeeperThread {
         private long lastPingSentNs;
         private final ClientCnxnSocket clientCnxnSocket;
         private Random r = new Random(System.nanoTime());        
@@ -946,7 +939,6 @@ public class ClientCnxn {
             super(makeThreadName("-SendThread()"));
             state = States.CONNECTING;
             this.clientCnxnSocket = clientCnxnSocket;
-            setUncaughtExceptionHandler(uncaughtExceptionHandler);
             setDaemon(true);
         }
 

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NIOServerCnxnFactory.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NIOServerCnxnFactory.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NIOServerCnxnFactory.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NIOServerCnxnFactory.java Sun Mar 23 03:12:56 2014
@@ -118,7 +118,7 @@ public class NIOServerCnxnFactory extend
      * of code shared by the AcceptThread (which selects on the listen socket)
      * and SelectorThread (which selects on client connections) classes.
      */
-    private abstract class AbstractSelectThread extends Thread {
+    private abstract class AbstractSelectThread extends ZooKeeperThread {
         protected final Selector selector;
 
         public AbstractSelectThread(String name) throws IOException {
@@ -561,7 +561,7 @@ public class NIOServerCnxnFactory extend
      * This thread is responsible for closing stale connections so that
      * connections on which no session is established are properly expired.
      */
-    private class ConnectionExpirerThread extends Thread {
+    private class ConnectionExpirerThread extends ZooKeeperThread {
         ConnectionExpirerThread() {
             super("ConnnectionExpirer");
         }

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java Sun Mar 23 03:12:56 2014
@@ -22,7 +22,6 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.StringReader;
 import java.nio.ByteBuffer;
-import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -32,7 +31,6 @@ import java.util.ListIterator;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.LinkedBlockingQueue;
 
@@ -89,7 +87,8 @@ import org.apache.zookeeper.txn.TxnHeade
  * outstandingRequests, so that it can take into account transactions that are
  * in the queue to be applied when generating a transaction.
  */
-public class PrepRequestProcessor extends Thread implements RequestProcessor {
+public class PrepRequestProcessor extends ZooKeeperCriticalThread implements
+        RequestProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(PrepRequestProcessor.class);
 
     static boolean skipACL;

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SessionTrackerImpl.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SessionTrackerImpl.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SessionTrackerImpl.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SessionTrackerImpl.java Sun Mar 23 03:12:56 2014
@@ -36,7 +36,8 @@ import org.slf4j.LoggerFactory;
  * period. Sessions are thus expired in batches made up of sessions that expire
  * in a given interval.
  */
-public class SessionTrackerImpl extends Thread implements SessionTracker {
+public class SessionTrackerImpl extends ZooKeeperCriticalThread implements
+        SessionTracker {
     private static final Logger LOG = LoggerFactory.getLogger(SessionTrackerImpl.class);
 
     protected final ConcurrentHashMap<Long, SessionImpl> sessionsById =

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SyncRequestProcessor.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SyncRequestProcessor.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SyncRequestProcessor.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/SyncRequestProcessor.java Sun Mar 23 03:12:56 2014
@@ -44,7 +44,8 @@ import org.slf4j.LoggerFactory;
  *             be null. This change the semantic of txnlog on the observer
  *             since it only contains committed txns.
  */
-public class SyncRequestProcessor extends Thread implements RequestProcessor {
+public class SyncRequestProcessor extends ZooKeeperCriticalThread implements
+        RequestProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(SyncRequestProcessor.class);
     private final ZooKeeperServer zks;
     private final LinkedBlockingQueue<Request> queuedRequests =
@@ -128,7 +129,7 @@ public class SyncRequestProcessor extend
                             if (snapInProcess != null && snapInProcess.isAlive()) {
                                 LOG.warn("Too busy to snap, skipping");
                             } else {
-                                snapInProcess = new Thread("Snapshot Thread") {
+                                snapInProcess = new ZooKeeperThread("Snapshot Thread") {
                                         public void run() {
                                             try {
                                                 zks.takeSnapshot();
@@ -161,9 +162,9 @@ public class SyncRequestProcessor extend
                 }
             }
         } catch (Throwable t) {
-            LOG.error("Severe unrecoverable error, exiting", t);
+            super.handleException(this.getName(), t);
+        } finally{
             running = false;
-            System.exit(11);
         }
         LOG.info("SyncRequestProcessor exited!");
     }

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/WorkerService.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/WorkerService.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/WorkerService.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/WorkerService.java Sun Mar 23 03:12:56 2014
@@ -130,14 +130,23 @@ public class WorkerService {
                 workRequest.cleanup();
             }
         } else {
-            scheduledWorkRequest.run();
+            // When there is no worker thread pool, do the work directly
+            // and wait for its completion
+            scheduledWorkRequest.start();
+            try {
+                scheduledWorkRequest.join();
+            } catch (InterruptedException e) {
+                LOG.warn("Unexpected exception", e);
+                Thread.currentThread().interrupt();
+            }
         }
     }
 
-    private class ScheduledWorkRequest implements Runnable {
+    private class ScheduledWorkRequest extends ZooKeeperThread {
         private final WorkRequest workRequest;
 
         ScheduledWorkRequest(WorkRequest workRequest) {
+            super("ScheduledWorkRequest");
             this.workRequest = workRequest;
         }
 

Added: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java?rev=1580436&view=auto
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java (added)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java Sun Mar 23 03:12:56 2014
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.server;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents critical thread. When there is an uncaught exception thrown by the
+ * thread this will exit the system.
+ */
+public class ZooKeeperCriticalThread extends ZooKeeperThread {
+    private static final Logger LOG = LoggerFactory
+            .getLogger(ZooKeeperCriticalThread.class);
+    private static final int DEFAULT_EXIT_CODE = 1;
+
+    public ZooKeeperCriticalThread(String threadName) {
+        super(threadName);
+    }
+
+    /**
+     * This will be used by the uncaught exception handler and make the system
+     * exit.
+     * 
+     * @param thName
+     *            - thread name
+     * @param e
+     *            - exception object
+     */
+    @Override
+    protected void handleException(String thName, Throwable e) {
+        LOG.error("Severe unrecoverable error, from thread : {}", thName, e);
+        System.exit(DEFAULT_EXIT_CODE);
+    }
+}

Added: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperThread.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperThread.java?rev=1580436&view=auto
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperThread.java (added)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperThread.java Sun Mar 23 03:12:56 2014
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.server;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the main class for catching all the uncaught exceptions thrown by the
+ * threads.
+ */
+public class ZooKeeperThread extends Thread {
+
+    private static final Logger LOG = LoggerFactory
+            .getLogger(ZooKeeperThread.class);
+
+    private UncaughtExceptionHandler uncaughtExceptionalHandler = new UncaughtExceptionHandler() {
+
+        @Override
+        public void uncaughtException(Thread t, Throwable e) {
+            handleException(t.getName(), e);
+        }
+    };
+
+    public ZooKeeperThread(String threadName) {
+        super(threadName);
+        setUncaughtExceptionHandler(uncaughtExceptionalHandler);
+    }
+
+    /**
+     * This will be used by the uncaught exception handler and just log a
+     * warning message and return.
+     * 
+     * @param thName
+     *            - thread name
+     * @param e
+     *            - exception object
+     */
+    protected void handleException(String thName, Throwable e) {
+        LOG.warn("Exception occured from thread {}", thName, e);
+    }
+}

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/AuthFastLeaderElection.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/AuthFastLeaderElection.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/AuthFastLeaderElection.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/AuthFastLeaderElection.java Sun Mar 23 03:12:56 2014
@@ -39,6 +39,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.zookeeper.jmx.MBeanRegistry;
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.quorum.Election;
 import org.apache.zookeeper.server.quorum.Vote;
 import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer;
@@ -206,12 +207,13 @@ public class AuthFastLeaderElection impl
         final ConcurrentHashMap<Long, Semaphore> ackMutex;
         final ConcurrentHashMap<InetSocketAddress, ConcurrentHashMap<Long, Long>> addrChallengeMap;
 
-        class WorkerReceiver implements Runnable {
+        class WorkerReceiver extends ZooKeeperThread {
 
             DatagramSocket mySocket;
             Messenger myMsg;
 
             WorkerReceiver(DatagramSocket s, Messenger msg) {
+                super("WorkerReceiver-" + s.getRemoteSocketAddress());
                 mySocket = s;
                 myMsg = msg;
             }
@@ -397,7 +399,7 @@ public class AuthFastLeaderElection impl
             }
         }
 
-        class WorkerSender implements Runnable {
+        class WorkerSender extends ZooKeeperThread {
 
             Random rand;
             int maxAttempts;
@@ -408,6 +410,7 @@ public class AuthFastLeaderElection impl
              */
 
             WorkerSender(int attempts) {
+                super("WorkerSender");
                 maxAttempts = attempts;
                 rand = new Random(java.lang.Thread.currentThread().getId()
                         + System.currentTimeMillis());

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java Sun Mar 23 03:12:56 2014
@@ -28,6 +28,7 @@ import org.apache.zookeeper.ZooDefs.OpCo
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.RequestProcessor;
 import org.apache.zookeeper.server.WorkerService;
+import org.apache.zookeeper.server.ZooKeeperCriticalThread;
 
 /**
  * This RequestProcessor matches the incoming committed requests with the
@@ -62,7 +63,8 @@ import org.apache.zookeeper.server.Worke
  * The current implementation solves the third constraint by simply allowing no
  * read requests to be processed in parallel with write requests.
  */
-public class CommitProcessor extends Thread implements RequestProcessor {
+public class CommitProcessor extends ZooKeeperCriticalThread implements
+        RequestProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(CommitProcessor.class);
 
     /** Default: numCores */

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FastLeaderElection.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FastLeaderElection.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FastLeaderElection.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FastLeaderElection.java Sun Mar 23 03:12:56 2014
@@ -28,6 +28,7 @@ import java.util.concurrent.LinkedBlocki
 import java.util.concurrent.TimeUnit;
 
 import org.apache.zookeeper.jmx.MBeanRegistry;
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.quorum.QuorumCnxManager.Message;
 import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
 import org.apache.zookeeper.server.quorum.QuorumPeer.ServerState;
@@ -207,11 +208,12 @@ public class FastLeaderElection implemen
          * method run(), and processes such messages.
          */
 
-        class WorkerReceiver implements Runnable {
+        class WorkerReceiver extends ZooKeeperThread  {
             volatile boolean stop;
             QuorumCnxManager manager;
 
             WorkerReceiver(QuorumCnxManager manager) {
+                super("WorkerReceiver");
                 this.stop = false;
                 this.manager = manager;
             }
@@ -419,11 +421,12 @@ public class FastLeaderElection implemen
          * and queues it on the manager's queue.
          */
 
-        class WorkerSender implements Runnable {
+        class WorkerSender extends ZooKeeperThread {
             volatile boolean stop;
             QuorumCnxManager manager;
 
             WorkerSender(QuorumCnxManager manager){
+                super("WorkerSender");
                 this.stop = false;
                 this.manager = manager;
             }

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java Sun Mar 23 03:12:56 2014
@@ -25,6 +25,7 @@ import org.apache.zookeeper.KeeperExcept
 import org.apache.zookeeper.ZooDefs.OpCode;
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.RequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperCriticalThread;
 import org.apache.zookeeper.server.ZooTrace;
 import org.apache.zookeeper.txn.ErrorTxn;
 import org.slf4j.Logger;
@@ -34,7 +35,7 @@ import org.slf4j.LoggerFactory;
  * This RequestProcessor forwards any requests that modify the state of the
  * system to the Leader.
  */
-public class FollowerRequestProcessor extends Thread implements
+public class FollowerRequestProcessor extends ZooKeeperCriticalThread implements
         RequestProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(FollowerRequestProcessor.class);
 

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java Sun Mar 23 03:12:56 2014
@@ -21,7 +21,6 @@ package org.apache.zookeeper.server.quor
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.net.BindException;
-import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketAddress;
@@ -44,10 +43,10 @@ import org.apache.zookeeper.ZooDefs.OpCo
 import org.apache.zookeeper.server.FinalRequestProcessor;
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.RequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
 import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
 import org.apache.zookeeper.server.util.ZxidUtils;
-import org.apache.zookeeper.server.ZooKeeperServer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -388,9 +387,13 @@ public class Leader {
 
     private final Proposal newLeaderProposal = new Proposal();
 
-    class LearnerCnxAcceptor extends Thread{
+    class LearnerCnxAcceptor extends ZooKeeperThread {
         private volatile boolean stop = false;
 
+        public LearnerCnxAcceptor() {
+            super("LearnerCnxAcceptor-" + ss.getLocalSocketAddress());
+        }
+
         @Override
         public void run() {
             try {
@@ -459,7 +462,6 @@ public class Leader {
             // Start thread that waits for connection requests from
             // new followers.
             cnxAcceptor = new LearnerCnxAcceptor();
-            cnxAcceptor.setName("LearnerCnxAcceptor-" + ss.getLocalSocketAddress());
             cnxAcceptor.start();
 
             long epoch = getEpochToPropose(self.getId(), self.getAcceptedEpoch());

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java Sun Mar 23 03:12:56 2014
@@ -41,6 +41,7 @@ import org.apache.zookeeper.ZooDefs.OpCo
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.TxnLogProposalIterator;
 import org.apache.zookeeper.server.ZKDatabase;
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.ZooTrace;
 import org.apache.zookeeper.server.quorum.Leader.Proposal;
 import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
@@ -55,7 +56,7 @@ import org.slf4j.LoggerFactory;
  * learner. All communication with a learner is handled by this
  * class.
  */
-public class LearnerHandler extends Thread {
+public class LearnerHandler extends ZooKeeperThread {
     private static final Logger LOG = LoggerFactory.getLogger(LearnerHandler.class);
 
     protected final Socket sock;

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ObserverRequestProcessor.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ObserverRequestProcessor.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ObserverRequestProcessor.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ObserverRequestProcessor.java Sun Mar 23 03:12:56 2014
@@ -28,6 +28,7 @@ import org.apache.zookeeper.KeeperExcept
 import org.apache.zookeeper.ZooDefs.OpCode;
 import org.apache.zookeeper.server.RequestProcessor;
 import org.apache.zookeeper.server.Request;
+import org.apache.zookeeper.server.ZooKeeperCriticalThread;
 import org.apache.zookeeper.server.ZooTrace;
 import org.apache.zookeeper.txn.ErrorTxn;
 
@@ -35,7 +36,7 @@ import org.apache.zookeeper.txn.ErrorTxn
  * This RequestProcessor forwards any requests that modify the state of the
  * system to the Leader.
  */
-public class ObserverRequestProcessor extends Thread implements
+public class ObserverRequestProcessor extends ZooKeeperCriticalThread implements
         RequestProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(ObserverRequestProcessor.class);
 

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java Sun Mar 23 03:12:56 2014
@@ -34,6 +34,8 @@ import java.util.concurrent.ConcurrentHa
 import java.util.concurrent.TimeUnit;
 import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -509,10 +511,16 @@ public class QuorumCnxManager {
     /**
      * Thread to listen on some port
      */
-    public class Listener extends Thread {
+    public class Listener extends ZooKeeperThread {
 
         volatile ServerSocket ss = null;
 
+        public Listener() {
+            // During startup of thread, thread name will be overridden to
+            // specific election address
+            super("ListenerThread");
+        }
+
         /**
          * Sleeps on accept().
          */
@@ -592,7 +600,7 @@ public class QuorumCnxManager {
      * soon as there is one available. If connection breaks, then opens a new
      * one.
      */
-    class SendWorker extends Thread {
+    class SendWorker extends ZooKeeperThread {
         Long sid;
         Socket sock;
         RecvWorker recvWorker;
@@ -746,7 +754,7 @@ public class QuorumCnxManager {
      * Thread to receive messages. Instance waits on a socket read. If the
      * channel breaks, then removes itself from the pool of receivers.
      */
-    class RecvWorker extends Thread {
+    class RecvWorker extends ZooKeeperThread {
         Long sid;
         Socket sock;
         volatile boolean running = true;

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java Sun Mar 23 03:12:56 2014
@@ -53,6 +53,7 @@ import org.apache.zookeeper.server.DataN
 import org.apache.zookeeper.server.ServerCnxnFactory;
 import org.apache.zookeeper.server.ZKDatabase;
 import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
 import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException;
 import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
@@ -88,7 +89,7 @@ import org.slf4j.LoggerFactory;
  *
  * The request for the current leader will consist solely of an xid: int xid;
  */
-public class QuorumPeer extends Thread implements QuorumStats.Provider {
+public class QuorumPeer extends ZooKeeperThread implements QuorumStats.Provider {
     private static final Logger LOG = LoggerFactory.getLogger(QuorumPeer.class);
 
     QuorumBean jmxQuorumBean;
@@ -448,7 +449,7 @@ public class QuorumPeer extends Thread i
      *
      */
     @Deprecated
-    class ResponderThread extends Thread {
+    class ResponderThread extends ZooKeeperThread {
         ResponderThread() {
             super("ResponderThread");
         }

Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ReadOnlyRequestProcessor.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ReadOnlyRequestProcessor.java?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ReadOnlyRequestProcessor.java (original)
+++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ReadOnlyRequestProcessor.java Sun Mar 23 03:12:56 2014
@@ -26,6 +26,7 @@ import org.apache.zookeeper.ZooDefs.OpCo
 import org.apache.zookeeper.proto.ReplyHeader;
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.RequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperCriticalThread;
 import org.apache.zookeeper.server.ZooKeeperServer;
 import org.apache.zookeeper.server.ZooTrace;
 import org.apache.zookeeper.server.quorum.Leader.XidRolloverException;
@@ -38,7 +39,8 @@ import org.slf4j.LoggerFactory;
  * OpCode.getData, OpCode.exists) through to the next processor, but drops
  * state-changing operations (e.g. OpCode.create, OpCode.setData).
  */
-public class ReadOnlyRequestProcessor extends Thread implements RequestProcessor {
+public class ReadOnlyRequestProcessor extends ZooKeeperCriticalThread implements
+        RequestProcessor {
 
     private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyRequestProcessor.class);
 

Modified: zookeeper/trunk/src/java/test/config/findbugsExcludeFile.xml
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/config/findbugsExcludeFile.xml?rev=1580436&r1=1580435&r2=1580436&view=diff
==============================================================================
--- zookeeper/trunk/src/java/test/config/findbugsExcludeFile.xml (original)
+++ zookeeper/trunk/src/java/test/config/findbugsExcludeFile.xml Sun Mar 23 03:12:56 2014
@@ -10,8 +10,8 @@
        In particular we want to make sure we exit if this occurs
        Also notice logged as fatal error -->
   <Match>
-    <Class name="org.apache.zookeeper.server.SyncRequestProcessor" />
-    <Method name="run" />
+    <Class name="org.apache.zookeeper.server.ZooKeeperCriticalThread" />
+    <Method name="handleException" />
     <Bug pattern="DM_EXIT" />
   </Match>
 

Added: zookeeper/trunk/src/java/test/org/apache/zookeeper/server/ZooKeeperThreadTest.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/server/ZooKeeperThreadTest.java?rev=1580436&view=auto
==============================================================================
--- zookeeper/trunk/src/java/test/org/apache/zookeeper/server/ZooKeeperThreadTest.java (added)
+++ zookeeper/trunk/src/java/test/org/apache/zookeeper/server/ZooKeeperThreadTest.java Sun Mar 23 03:12:56 2014
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.server;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class ZooKeeperThreadTest {
+    private CountDownLatch runningLatch = new CountDownLatch(1);
+
+    public class MyThread extends ZooKeeperThread {
+
+        public MyThread(String threadName) {
+            super(threadName);
+        }
+
+        public void run() {
+            throw new Error();
+        }
+
+        @Override
+        protected void handleException(String thName, Throwable e) {
+            runningLatch.countDown();
+        }
+    }
+
+    public class MyCriticalThread extends ZooKeeperCriticalThread {
+
+        public MyCriticalThread(String threadName) {
+            super(threadName);
+        }
+
+        public void run() {
+            throw new Error();
+        }
+
+        @Override
+        protected void handleException(String thName, Throwable e) {
+            runningLatch.countDown();
+        }
+    }
+
+    /**
+     * Test verifies uncaught exception handling of ZooKeeperThread
+     */
+    @Test(timeout = 30000)
+    public void testUncaughtException() throws Exception {
+        MyThread t1 = new MyThread("Test-Thread");
+        t1.start();
+        Assert.assertTrue("Uncaught exception is not properly handled.",
+                runningLatch.await(10000, TimeUnit.MILLISECONDS));
+
+        runningLatch = new CountDownLatch(1);
+        MyCriticalThread t2 = new MyCriticalThread("Test-Critical-Thread");
+        t2.start();
+        Assert.assertTrue("Uncaught exception is not properly handled.",
+                runningLatch.await(10000, TimeUnit.MILLISECONDS));
+    }
+}