hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nkey...@apache.org
Subject svn commit: r1537425 - in /hbase/trunk: hbase-client/src/main/java/org/apache/hadoop/hbase/client/ hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/ hbase-server/src/test/java/org/apache/hadoop/hbase/client/
Date Thu, 31 Oct 2013 10:29:30 GMT
Author: nkeywal
Date: Thu Oct 31 10:29:30 2013
New Revision: 1537425

URL: http://svn.apache.org/r1537425
Log:
HBASE-9861 Location does not have to be refreshed on regionTooBusy

Modified:
    hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
    hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionMovedException.java
    hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionOpeningException.java
    hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java

Modified: hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1537425&r1=1537424&r2=1537425&view=diff
==============================================================================
--- hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
(original)
+++ hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
Thu Oct 31 10:29:30 2013
@@ -56,6 +56,7 @@ import org.apache.hadoop.hbase.HRegionIn
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.MasterNotRunningException;
+import org.apache.hadoop.hbase.RegionTooBusyException;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.Stoppable;
 import org.apache.hadoop.hbase.TableName;
@@ -2208,7 +2209,8 @@ public class HConnectionManager {
 
     /**
      * Update the location with the new value (if the exception is a RegionMovedException)
-     * or delete it from the cache.
+     * or delete it from the cache. Does nothing if we can be sure from the exception that
+     * the location is still accurate, or if the cache has already been updated.
      * @param exception an object (to simplify user code) on which we will try to find a
nested
      *                  or wrapped or both RegionMovedException
      * @param source server that is the source of the location update.
@@ -2222,30 +2224,45 @@ public class HConnectionManager {
         return;
       }
 
+      if (source == null || source.getServerName() == null){
+        // This should not happen, but let's secure ourselves.
+        return;
+      }
+
       // Is it something we have already updated?
       final HRegionLocation oldLocation = getCachedLocation(tableName, rowkey);
-      if (oldLocation == null) {
-        // There is no such location in the cache => it's been removed already => nothing
to do
+      if (oldLocation == null || !source.getServerName().equals(oldLocation.getServerName()))
{
+        // There is no such location in the cache (it's been removed already) or
+        // the cache has already been refreshed with a different location.  => nothing
to do
         return;
       }
 
       HRegionInfo regionInfo = oldLocation.getRegionInfo();
-      final RegionMovedException rme = RegionMovedException.find(exception);
-      if (rme != null) {
-        if (LOG.isTraceEnabled()){
-          LOG.trace("Region " + regionInfo.getRegionNameAsString() + " moved to " +
-            rme.getHostname() + ":" + rme.getPort() + " according to " + source.getHostnamePort());
-        }
-        updateCachedLocation(
-            regionInfo, source, rme.getServerName(), rme.getLocationSeqNum());
-      } else if (RegionOpeningException.find(exception) != null) {
-        if (LOG.isTraceEnabled()) {
-          LOG.trace("Region " + regionInfo.getRegionNameAsString() + " is being opened on
"
-              + source.getHostnamePort() + "; not deleting the cache entry");
+      Throwable cause = findException(exception);
+      if (cause != null) {
+        if (cause instanceof RegionTooBusyException || cause instanceof RegionOpeningException)
{
+          // We know that the region is still on this region server
+          return;
+        }
+
+        if (cause instanceof RegionMovedException) {
+          RegionMovedException rme = (RegionMovedException) cause;
+          if (LOG.isTraceEnabled()) {
+            LOG.trace("Region " + regionInfo.getRegionNameAsString() + " moved to " +
+                rme.getHostname() + ":" + rme.getPort() +
+                " according to " + source.getHostnamePort());
+          }
+          // We know that the region is not anymore on this region server, but we know
+          //  the new location.
+          updateCachedLocation(
+              regionInfo, source, rme.getServerName(), rme.getLocationSeqNum());
+          return;
         }
-      } else {
-        deleteCachedLocation(regionInfo, source);
       }
+
+      // If we're here, it means that can cannot be sure about the location, so we remove
it from
+      //  the cache.
+      deleteCachedLocation(regionInfo, source);
     }
 
     @Override
@@ -2714,6 +2731,46 @@ public class HConnectionManager {
   }
 
   /**
+   * Look for an exception we know in the remote exception:
+   * - hadoop.ipc wrapped exceptions
+   * - nested exceptions
+   * 
+   * Looks for: RegionMovedException / RegionOpeningException / RegionTooBusyException
+   * @returns null if we didn't find the exception, the exception otherwise.
+   */
+  public static Throwable findException(Object exception) {
+    if (exception == null || !(exception instanceof Throwable)) {
+      return null;
+    }
+    Throwable cur = (Throwable) exception;
+    while (cur != null) {
+      if (cur instanceof RegionMovedException || cur instanceof RegionOpeningException
+          || cur instanceof RegionTooBusyException) {
+        return cur;
+      }
+      if (cur instanceof RemoteException) {
+        RemoteException re = (RemoteException) cur;
+        cur = re.unwrapRemoteException(
+            RegionOpeningException.class, RegionMovedException.class,
+            RegionTooBusyException.class);
+        if (cur == null) {
+          cur = re.unwrapRemoteException();
+        }
+        // unwrapRemoteException can return the exception given as a parameter when it cannot
+        //  unwrap it. In this case, there is no need to look further
+        // noinspection ObjectEquality
+        if (cur == re) {
+          return null;
+        }
+      } else {
+        cur = cur.getCause();
+      }
+    }
+
+    return null;
+  }
+
+  /**
    * Set the number of retries to use serverside when trying to communicate
    * with another server over {@link HConnection}.  Used updating catalog
    * tables, etc.  Call this method before we create any Connections.

Modified: hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionMovedException.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionMovedException.java?rev=1537425&r1=1537424&r2=1537425&view=diff
==============================================================================
--- hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionMovedException.java
(original)
+++ hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionMovedException.java
Thu Oct 31 10:29:30 2013
@@ -109,47 +109,4 @@ public class RegionMovedException extend
     return "Region moved to: " + HOST_FIELD + hostname + " " + PORT_FIELD + port + " " +
         STARTCODE_FIELD + startCode + ". As of "  + LOCATIONSEQNUM_FIELD + locationSeqNum
+ ".";
   }
-
-  /**
-   * Look for a RegionMovedException in the exception:
-   *  - hadoop.ipc wrapped exceptions
-   *  - nested exceptions
-   * Returns null if we didn't find the exception or if it was not readable.
-   */
-  public static RegionMovedException find(Object exception) {
-    if (exception == null || !(exception instanceof Throwable)){
-      return null;
-    }
-
-    Throwable cur = (Throwable)exception;
-    RegionMovedException res = null;
-
-    while (res == null && cur != null) {
-      if (cur instanceof RegionMovedException) {
-        res = (RegionMovedException) cur;
-      } else {
-        if (cur instanceof RemoteException) {
-          RemoteException re = (RemoteException) cur;
-          Exception e = re.unwrapRemoteException(RegionMovedException.class);
-          if (e == null){
-            e = re.unwrapRemoteException();
-          }
-          // unwrapRemoteException can return the exception given as a parameter when it
cannot
-          //  unwrap it. In this case, there is no need to look further
-          // noinspection ObjectEquality
-          if (e != re){
-            res =  find(e);
-          }
-        }
-        cur = cur.getCause();
-      }
-    }
-
-    if (res != null && (res.getPort() < 0 || res.getHostname() == null)){
-      // We failed to parse the exception. Let's act as we don't find the exception.
-      return null;
-    } else {
-      return res;
-    }
-  }
 }

Modified: hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionOpeningException.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionOpeningException.java?rev=1537425&r1=1537424&r2=1537425&view=diff
==============================================================================
--- hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionOpeningException.java
(original)
+++ hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/RegionOpeningException.java
Thu Oct 31 10:29:30 2013
@@ -38,42 +38,4 @@ public class RegionOpeningException exte
   public RegionOpeningException(String message) {
     super(message);
   }
-
-  /**
-   * Look for a RegionOpeningException in the exception:
-   *  - hadoop.ipc wrapped exceptions
-   *  - nested exceptions
-   * Returns null if we didn't find the exception.
-   * TODO: this code is mostly C/Ped from RegionMovedExecption. Due to the limitations of
-   *       generics it's not amenable to generalizing without adding parameters/isAssignableFrom.
-   *       Might make general if used in more places.
-   */
-  public static RegionOpeningException find(Object exception) {
-    if (exception == null || !(exception instanceof Throwable)) {
-      return null;
-    }
-    RegionOpeningException res = null;
-    Throwable cur = (Throwable)exception;
-    while (res == null && cur != null) {
-      if (cur instanceof RegionOpeningException) {
-        res = (RegionOpeningException) cur;
-      } else {
-        if (cur instanceof RemoteException) {
-          RemoteException re = (RemoteException) cur;
-          Exception e = re.unwrapRemoteException(RegionOpeningException.class);
-          if (e == null) {
-            e = re.unwrapRemoteException();
-          }
-          // unwrapRemoteException can return the exception given as a parameter when it
cannot
-          //  unwrap it. In this case, there is no need to look further
-          // noinspection ObjectEquality
-          if (e != re) {
-            res = find(e);
-          }
-        }
-        cur = cur.getCause();
-      }
-    }
-    return res;
-  }
 }
\ No newline at end of file

Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java?rev=1537425&r1=1537424&r2=1537425&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java Thu
Oct 31 10:29:30 2013
@@ -54,6 +54,7 @@ import org.apache.hadoop.hbase.TableName
 import org.apache.hadoop.hbase.Waiter;
 import org.apache.hadoop.hbase.client.HConnectionManager.HConnectionImplementation;
 import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.exceptions.RegionMovedException;
 import org.apache.hadoop.hbase.filter.Filter;
 import org.apache.hadoop.hbase.filter.FilterBase;
 import org.apache.hadoop.hbase.master.HMaster;
@@ -449,12 +450,18 @@ public class TestHCM {
     } catch (RetriesExhaustedWithDetailsException e){
       LOG.info("Put done, exception caught: " + e.getClass());
       Assert.assertEquals(1, e.getNumExceptions());
+      Assert.assertEquals(1, e.getCauses().size());
       Assert.assertArrayEquals(e.getRow(0).getRow(), ROW);
+
+      // Check that we unserialized the exception as expected
+      Throwable cause = HConnectionManager.findException(e.getCause(0));
+      Assert.assertNotNull(cause);
+      Assert.assertTrue(cause instanceof RegionMovedException);
     }
     Assert.assertNotNull("Cached connection is null", conn.getCachedLocation(TABLE_NAME,
ROW));
     Assert.assertEquals(
-      "Previous server was "+curServer.getServerName().getHostAndPort(),
-      destServerName.getPort(), conn.getCachedLocation(TABLE_NAME, ROW).getPort());
+        "Previous server was " + curServer.getServerName().getHostAndPort(),
+        destServerName.getPort(), conn.getCachedLocation(TABLE_NAME, ROW).getPort());
 
     Assert.assertFalse(destServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes));
     Assert.assertFalse(curServer.getRegionsInTransitionInRS().containsKey(encodedRegionNameBytes));



Mime
View raw message