Repository: hbase Updated Branches: refs/heads/HBASE-14850 8335e1529 -> f27075a6f
HBASE-18188 [C++] Fix Handling do not retry exceptions Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/f27075a6 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/f27075a6 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/f27075a6 Branch: refs/heads/HBASE-14850 Commit: f27075a6fa0a3219ef87421339b2a11af9e2df30 Parents: 8335e15 Author: Enis Soztutar <e...@apache.org> Authored: Fri Jun 16 11:38:22 2017 -0700 Committer: Enis Soztutar <e...@apache.org> Committed: Fri Jun 16 11:38:22 2017 -0700 ---------------------------------------------------------------------- hbase-native-client/bin/cpplint.sh | 2 +- hbase-native-client/core/client-test.cc | 11 +- hbase-native-client/core/location-cache.cc | 4 +- hbase-native-client/exceptions/BUCK | 13 +- .../exceptions/exception-test.cc | 64 ++++++ hbase-native-client/exceptions/exception.cc | 128 ++++++++++++ hbase-native-client/exceptions/exception.h | 201 +++++++++++++------ 7 files changed, 362 insertions(+), 61 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/bin/cpplint.sh ---------------------------------------------------------------------- diff --git a/hbase-native-client/bin/cpplint.sh b/hbase-native-client/bin/cpplint.sh index 81795fd..3684c2e 100755 --- a/hbase-native-client/bin/cpplint.sh +++ b/hbase-native-client/bin/cpplint.sh @@ -27,4 +27,4 @@ wget -nc $CPPLINT_LOC -O $OUTPUT # Exclude the following rules: build/header_guard (We use #pragma once instead) # readability/todo (TODOs are generic) # build/c++11 (We are building with c++14) -find core connection serde utils test-util security -name "*.h" -or -name "*.cc" | xargs -P8 python $OUTPUT --filter=-build/header_guard,-readability/todo,-build/c++11 --linelength=100 +find core connection exceptions serde utils test-util security -name "*.h" -or -name "*.cc" | xargs -P8 python $OUTPUT --filter=-build/header_guard,-readability/todo,-build/c++11 --linelength=100 http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/core/client-test.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/client-test.cc b/hbase-native-client/core/client-test.cc index ed413e8..6462e6a 100644 --- a/hbase-native-client/core/client-test.cc +++ b/hbase-native-client/core/client-test.cc @@ -30,6 +30,7 @@ #include "core/put.h" #include "core/result.h" #include "core/table.h" +#include "exceptions/exception.h" #include "serde/table-name.h" #include "test-util/test-util.h" #include "utils/bytes-util.h" @@ -37,6 +38,7 @@ using hbase::Cell; using hbase::Configuration; using hbase::Get; +using hbase::RetriesExhaustedException; using hbase::Put; using hbase::Table; using hbase::TestUtil; @@ -326,7 +328,14 @@ TEST_F(ClientTest, GetForNonExistentTable) { ASSERT_TRUE(table) << "Unable to get connection to Table."; // Perform the Get - ASSERT_ANY_THROW(table->Get(get)) << "Table does not exist. We should get an exception"; + try { + table->Get(get); + FAIL() << "Should have thrown RetriesExhaustedException"; + } catch (const RetriesExhaustedException &ex) { + ASSERT_EQ(0, ex.num_retries()); + } catch (...) { + FAIL() << "Should have thrown RetriesExhaustedException"; + } table->Close(); client.Close(); http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/core/location-cache.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/location-cache.cc b/hbase-native-client/core/location-cache.cc index d368314..dfe3e9f 100644 --- a/hbase-native-client/core/location-cache.cc +++ b/hbase-native-client/core/location-cache.cc @@ -24,9 +24,9 @@ #include <wangle/concurrent/CPUThreadPoolExecutor.h> #include <wangle/concurrent/IOThreadPoolExecutor.h> -#include <folly/Logging.h> #include "connection/response.h" #include "connection/rpc-connection.h" +#include "exceptions/exception.h" #include "if/Client.pb.h" #include "if/ZooKeeper.pb.h" #include "serde/region-info.h" @@ -127,7 +127,7 @@ folly::Future<std::shared_ptr<RegionLocation>> LocationCache::LocateFromMeta( // Make sure that the correct location was found. if (rl->region_info().table_name().namespace_() != tn.namespace_() || rl->region_info().table_name().qualifier() != tn.qualifier()) { - throw std::runtime_error("Doesn't look like table exists."); + throw TableNotFoundException(folly::to<std::string>(tn)); } return rl; }) http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/exceptions/BUCK ---------------------------------------------------------------------- diff --git a/hbase-native-client/exceptions/BUCK b/hbase-native-client/exceptions/BUCK index 07ffeaf..e2f03a1 100644 --- a/hbase-native-client/exceptions/BUCK +++ b/hbase-native-client/exceptions/BUCK @@ -20,9 +20,20 @@ cxx_library( exported_headers=[ "exception.h", ], - srcs=[], + srcs=[ + "exception.cc", + ], deps=[ "//third-party:folly", ], compiler_flags=['-Weffc++'], visibility=['//core/...', '//connection//...'],) +cxx_test( + name="exception-test", + srcs=[ + "exception-test.cc", + ], + deps=[ + ":exceptions", + ], + run_test_separately=True,) http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/exceptions/exception-test.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/exceptions/exception-test.cc b/hbase-native-client/exceptions/exception-test.cc new file mode 100644 index 0000000..583240e --- /dev/null +++ b/hbase-native-client/exceptions/exception-test.cc @@ -0,0 +1,64 @@ +/* + * 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. + * + */ +#include <gtest/gtest.h> + +#include "exceptions/exception.h" + +#include "folly/ExceptionWrapper.h" + +using hbase::ExceptionUtil; +using hbase::IOException; +using hbase::RemoteException; + +TEST(ExceptionUtilTest, IOExceptionShouldRetry) { + IOException ex{}; + EXPECT_TRUE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_do_not_retry(true); + EXPECT_FALSE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_do_not_retry(false); + EXPECT_TRUE(ExceptionUtil::ShouldRetry(ex)); + + IOException ex2{"description", true}; + EXPECT_FALSE(ExceptionUtil::ShouldRetry(ex2)); + + IOException ex3{"description", std::runtime_error("ex"), true}; + EXPECT_FALSE(ExceptionUtil::ShouldRetry(ex3)); +} + +TEST(ExceptionUtilTest, RemoteExceptionShouldRetry) { + RemoteException ex{}; + EXPECT_TRUE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_do_not_retry(true); + EXPECT_FALSE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_do_not_retry(false); + EXPECT_TRUE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_exception_class_name("org.apache.hadoop.hbase.FooException"); + EXPECT_TRUE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_exception_class_name("org.apache.hadoop.hbase.NotServingRegionException"); + EXPECT_TRUE(ExceptionUtil::ShouldRetry(ex)); + + ex.set_exception_class_name("org.apache.hadoop.hbase.UnknownRegionException"); + EXPECT_FALSE(ExceptionUtil::ShouldRetry(ex)); +} http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/exceptions/exception.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/exceptions/exception.cc b/hbase-native-client/exceptions/exception.cc new file mode 100644 index 0000000..c25acb4 --- /dev/null +++ b/hbase-native-client/exceptions/exception.cc @@ -0,0 +1,128 @@ +/* + * 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. + * + */ +#include "exceptions/exception.h" + +namespace hbase { +const std::vector<const char*> ExceptionUtil::kAllDoNotRetryIOExceptions = { + kDoNotRetryIOException, + kTableNotFoundException, + kTableNotEnabledException, + kCoprocessorException, + kBypassCoprocessorException, + kInvalidFamilyOperationException, + kServerTooBusyException, + kFailedSanityCheckException, + kCorruptHFileException, + kLabelAlreadyExistsException, + kFatalConnectionException, + kUnsupportedCryptoException, + kUnsupportedCellCodecException, + kEmptyServiceNameException, + kUnknownServiceException, + kWrongVersionException, + kBadAuthException, + kUnsupportedCompressionCodecException, + kDoNotRetryRegionException, + kRowTooBigException, + kRowTooBigExceptionDeprecated, + kUnknownRegionException, + kMergeRegionException, + kNoServerForRegionException, + kQuotaExceededException, + kSpaceLimitingException, + kThrottlingException, + kAccessDeniedException, + kUnknownProtocolException, + kRequestTooBigException, + kNotAllMetaRegionsOnlineException, + kConstraintException, + kNoSuchColumnFamilyException, + kLeaseException, + kInvalidLabelException, + kUnknownScannerException, + kScannerResetException, + kOutOfOrderScannerNextException}; + +bool ExceptionUtil::ShouldRetry(const folly::exception_wrapper& error) { + bool do_not_retry = false; + error.with_exception( + [&](const IOException& ioe) { do_not_retry = do_not_retry || ioe.do_not_retry(); }); + error.with_exception([&](const RemoteException& remote_ex) { + do_not_retry = do_not_retry || IsJavaDoNotRetryException(remote_ex.exception_class_name()); + }); + return !do_not_retry; +} + +/** + * Returns whether the java exception class extends DoNotRetryException. + * In the java side, we just have a hierarchy of Exception classes that we use + * both client side and server side. On the client side, we rethrow the server + * side exception by un-wrapping the exception from a RemoteException or a ServiceException + * (see ConnectionUtils.translateException() in Java). + * Since this object-hierarchy info is not available in C++ side, we are doing a + * very fragile catch-all list of all exception types in Java that extend the + * DoNotRetryException class type. + */ +bool ExceptionUtil::IsJavaDoNotRetryException(const std::string& java_class_name) { + for (auto exception : kAllDoNotRetryIOExceptions) { + if (java_class_name == exception) { + return true; + } + } + return false; +} + +/** + * Returns whether the scanner is closed when the client received the + * remote exception. + * Since the object-hierarchy info is not available in C++ side, we are doing a + * very fragile catch-all list of all exception types in Java that extend these + * three base classes: UnknownScannerException, NotServingRegionException, + * RegionServerStoppedException + */ +bool ExceptionUtil::IsScannerClosed(const folly::exception_wrapper& exception) { + bool scanner_closed = false; + exception.with_exception([&](const RemoteException& remote_ex) { + auto java_class = remote_ex.exception_class_name(); + if (java_class == kUnknownScannerException || java_class == kNotServingRegionException || + java_class == kRegionInRecoveryException || java_class == kRegionOpeningException || + java_class == kRegionMovedException || java_class == kRegionServerStoppedException || + java_class == kRegionServerAbortedException) { + scanner_closed = true; + } + }); + return scanner_closed; +} + +/** + * Returns whether the wrapped exception is a java exception of type OutOfOrderScannerNextException + * or ScannerResetException. These two exception types are thrown from the server side when the + * scanner on the server side is closed. + */ +bool ExceptionUtil::IsScannerOutOfOrder(const folly::exception_wrapper& exception) { + bool scanner_out_of_order = false; + exception.with_exception([&](const RemoteException& remote_ex) { + auto java_class = remote_ex.exception_class_name(); + if (java_class == kOutOfOrderScannerNextException || java_class == kScannerResetException) { + scanner_out_of_order = true; + } + }); + return scanner_out_of_order; +} +} // namespace hbase http://git-wip-us.apache.org/repos/asf/hbase/blob/f27075a6/hbase-native-client/exceptions/exception.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/exceptions/exception.h b/hbase-native-client/exceptions/exception.h index 9cbd7ae..bdedff4 100644 --- a/hbase-native-client/exceptions/exception.h +++ b/hbase-native-client/exceptions/exception.h @@ -21,6 +21,7 @@ #include <folly/ExceptionWrapper.h> #include <folly/io/IOBuf.h> #include <exception> +#include <memory> #include <string> #include <vector> @@ -28,10 +29,10 @@ namespace hbase { class ThrowableWithExtraContext { public: - ThrowableWithExtraContext(folly::exception_wrapper cause, const long& when) + ThrowableWithExtraContext(folly::exception_wrapper cause, const int64_t& when) : cause_(cause), when_(when), extras_("") {} - ThrowableWithExtraContext(folly::exception_wrapper cause, const long& when, + ThrowableWithExtraContext(folly::exception_wrapper cause, const int64_t& when, const std::string& extras) : cause_(cause), when_(when), extras_(extras) {} @@ -45,23 +46,44 @@ class ThrowableWithExtraContext { private: folly::exception_wrapper cause_; - long when_; + int64_t when_; std::string extras_; }; class IOException : public std::logic_error { public: - IOException() : logic_error("") {} + IOException() : logic_error(""), do_not_retry_(false) {} + + explicit IOException(const std::string& what) : logic_error(what), do_not_retry_(false) {} + + IOException(const std::string& what, bool do_not_retry) + : logic_error(what), do_not_retry_(do_not_retry) {} - IOException(const std::string& what) : logic_error(what) {} IOException(const std::string& what, folly::exception_wrapper cause) - : logic_error(what), cause_(cause) {} + : logic_error(what), cause_(cause), do_not_retry_(false) {} + + IOException(const std::string& what, folly::exception_wrapper cause, bool do_not_retry) + : logic_error(what), cause_(cause), do_not_retry_(do_not_retry) {} + virtual ~IOException() = default; virtual folly::exception_wrapper cause() { return cause_; } + bool do_not_retry() const { return do_not_retry_; } + + IOException* set_do_not_retry(bool value) { + do_not_retry_ = value; + return this; + } + private: folly::exception_wrapper cause_; + // In case the exception is a RemoteException, do_not_retry information can come from + // the PB field in the RPC response, or it can be deduced from the Java-exception + // hierarchy in ExceptionUtil::ShouldRetry(). In case this is a client-side exception + // raised from the C++ internals, set this field so that the retrying callers can + // re-throw the exception without retrying. + bool do_not_retry_; }; class RetriesExhaustedException : public IOException { @@ -70,9 +92,12 @@ class RetriesExhaustedException : public IOException { std::shared_ptr<std::vector<ThrowableWithExtraContext>> exceptions) : IOException(GetMessage(num_retries, exceptions), exceptions->empty() ? folly::exception_wrapper{} - : (*exceptions)[exceptions->size() - 1].cause()) {} + : (*exceptions)[exceptions->size() - 1].cause()), + num_retries_(num_retries) {} virtual ~RetriesExhaustedException() = default; + int32_t num_retries() const { return num_retries_; } + private: std::string GetMessage(const int& num_retries, std::shared_ptr<std::vector<ThrowableWithExtraContext>> exceptions) { @@ -85,18 +110,19 @@ class RetriesExhaustedException : public IOException { } return buffer; } -}; -class HBaseIOException : public IOException {}; + private: + int32_t num_retries_; +}; class RemoteException : public IOException { public: - RemoteException() : port_(0), do_not_retry_(false) {} + RemoteException() : IOException(), port_(0) {} - RemoteException(const std::string& what) : IOException(what), port_(0), do_not_retry_(false) {} + explicit RemoteException(const std::string& what) : IOException(what), port_(0) {} RemoteException(const std::string& what, folly::exception_wrapper cause) - : IOException(what, cause), port_(0), do_not_retry_(false) {} + : IOException(what, cause), port_(0) {} virtual ~RemoteException() = default; @@ -128,19 +154,23 @@ class RemoteException : public IOException { return this; } - bool do_not_retry() const { return do_not_retry_; } - - RemoteException* set_do_not_retry(bool value) { - do_not_retry_ = value; - return this; - } - private: std::string exception_class_name_; std::string stack_trace_; std::string hostname_; int port_; - bool do_not_retry_; +}; + +/** + * Raised from the client side if we cannot find the table (does not have anything to + * do with the Java exception of the same name). + */ +class TableNotFoundException : public IOException { + public: + explicit TableNotFoundException(const std::string& table_name) + : IOException("Table cannot be found:" + table_name, true) {} + + virtual ~TableNotFoundException() = default; }; /** @@ -174,54 +204,113 @@ class ExceptionUtil { static constexpr const char* kScannerResetException = "org.apache.hadoop.hbase.exceptions.ScannerResetException"; + // All other DoNotRetryIOExceptions + static constexpr const char* kDoNotRetryIOException = + "org.apache.hadoop.hbase.DoNotRetryIOException"; + static constexpr const char* kTableNotFoundException = + "org.apache.hadoop.hbase.TableNotFoundException"; + static constexpr const char* kTableNotEnabledException = + "org.apache.hadoop.hbase.TableNotEnabledException"; + static constexpr const char* kCoprocessorException = + "org.apache.hadoop.hbase.coprocessor.CoprocessorException"; + static constexpr const char* kBypassCoprocessorException = + "org.apache.hadoop.hbase.coprocessor.BypassCoprocessorException"; + static constexpr const char* kInvalidFamilyOperationException = + "org.apache.hadoop.hbase.InvalidFamilyOperationException"; + static constexpr const char* kServerTooBusyException = + "org.apache.hadoop.hbase.ipc.ServerTooBusyException"; // This should NOT be DNRIOE? + static constexpr const char* kFailedSanityCheckException = + "org.apache.hadoop.hbase.exceptions.FailedSanityCheckException"; + static constexpr const char* kCorruptHFileException = + "org.apache.hadoop.hbase.io.hfile.CorruptHFileException"; + static constexpr const char* kLabelAlreadyExistsException = + "org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException"; + static constexpr const char* kFatalConnectionException = + "org.apache.hadoop.hbase.ipc.FatalConnectionException"; + static constexpr const char* kUnsupportedCryptoException = + "org.apache.hadoop.hbase.ipc.UnsupportedCryptoException"; + static constexpr const char* kUnsupportedCellCodecException = + "org.apache.hadoop.hbase.ipc.UnsupportedCellCodecException"; + static constexpr const char* kEmptyServiceNameException = + "org.apache.hadoop.hbase.ipc.EmptyServiceNameException"; + static constexpr const char* kUnknownServiceException = + "org.apache.hadoop.hbase.ipc.UnknownServiceException"; + static constexpr const char* kWrongVersionException = + "org.apache.hadoop.hbase.ipc.WrongVersionException"; + static constexpr const char* kBadAuthException = "org.apache.hadoop.hbase.ipc.BadAuthException"; + static constexpr const char* kUnsupportedCompressionCodecException = + "org.apache.hadoop.hbase.ipc.UnsupportedCompressionCodecException"; + static constexpr const char* kDoNotRetryRegionException = + "org.apache.hadoop.hbase.client.DoNotRetryRegionException"; + static constexpr const char* kRowTooBigException = + "org.apache.hadoop.hbase.client.RowTooBigException"; + static constexpr const char* kRowTooBigExceptionDeprecated = + "org.apache.hadoop.hbase.regionserver.RowTooBigException"; + static constexpr const char* kUnknownRegionException = + "org.apache.hadoop.hbase.UnknownRegionException"; + static constexpr const char* kMergeRegionException = + "org.apache.hadoop.hbase.exceptions.MergeRegionException"; + static constexpr const char* kNoServerForRegionException = + "org.apache.hadoop.hbase.client.NoServerForRegionException"; + static constexpr const char* kQuotaExceededException = + "org.apache.hadoop.hbase.quotas.QuotaExceededException"; + static constexpr const char* kSpaceLimitingException = + "org.apache.hadoop.hbase.quotas.SpaceLimitingException"; + static constexpr const char* kThrottlingException = + "org.apache.hadoop.hbase.quotas.ThrottlingException"; + static constexpr const char* kAccessDeniedException = + "org.apache.hadoop.hbase.security.AccessDeniedException"; + static constexpr const char* kUnknownProtocolException = + "org.apache.hadoop.hbase.exceptions.UnknownProtocolException"; + static constexpr const char* kRequestTooBigException = + "org.apache.hadoop.hbase.exceptions.RequestTooBigException"; + static constexpr const char* kNotAllMetaRegionsOnlineException = + "org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException"; + static constexpr const char* kConstraintException = + "org.apache.hadoop.hbase.constraint.ConstraintException"; + static constexpr const char* kNoSuchColumnFamilyException = + "org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException"; + static constexpr const char* kLeaseException = + "org.apache.hadoop.hbase.regionserver.LeaseException"; + static constexpr const char* kInvalidLabelException = + "org.apache.hadoop.hbase.security.visibility.InvalidLabelException"; + + // TODO: + // These exceptions are not thrown in the regular read / write paths, although they are + // DoNotRetryIOExceptions. Add these to the list below in case we start doing Admin/DDL ops + // ReplicationPeerNotFoundException, XXXSnapshotException, NamespaceExistException, + // NamespaceNotFoundException, TableExistsException, TableNotDisabledException, + static const std::vector<const char*> kAllDoNotRetryIOExceptions; + public: /** * Returns whether or not the exception should be retried by looking at the - * remote exception. + * client-side IOException, or RemoteException coming from server side. */ - static bool ShouldRetry(const folly::exception_wrapper& error) { - bool do_not_retry = false; - error.with_exception( - [&](const RemoteException& remote_ex) { do_not_retry = remote_ex.do_not_retry(); }); - return !do_not_retry; - } + static bool ShouldRetry(const folly::exception_wrapper& error); /** - * Returns whether the scanner is closed when the client received the - * remote exception. - * Ok, here is a nice detail about the java exceptions. In the java side, we - * just have a hierarchy of Exception classes that we use both client side and - * server side. On the client side, we rethrow the server side exception by - * un-wrapping the exception from a RemoteException or a ServiceException + * Returns whether the java exception class extends DoNotRetryException. + * In the java side, we just have a hierarchy of Exception classes that we use + * both client side and server side. On the client side, we rethrow the server + * side exception by un-wrapping the exception from a RemoteException or a ServiceException * (see ConnectionUtils.translateException() in Java). * Since this object-hierarchy info is not available in C++ side, we are doing a + * very fragile catch-all list of all exception types in Java that extend the + * DoNotRetryException class type. + */ + static bool IsJavaDoNotRetryException(const std::string& java_class_name); + + /** + * Returns whether the scanner is closed when the client received the + * remote exception. + * Since the object-hierarchy info is not available in C++ side, we are doing a * very fragile catch-all list of all exception types in Java that extend these * three base classes: UnknownScannerException, NotServingRegionException, * RegionServerStoppedException */ - static bool IsScannerClosed(const folly::exception_wrapper& exception) { - bool scanner_closed = false; - exception.with_exception([&](const RemoteException& remote_ex) { - auto java_class = remote_ex.exception_class_name(); - if (java_class == kUnknownScannerException || java_class == kNotServingRegionException || - java_class == kRegionInRecoveryException || java_class == kRegionOpeningException || - java_class == kRegionMovedException || java_class == kRegionServerStoppedException || - java_class == kRegionServerAbortedException) { - scanner_closed = true; - } - }); - return scanner_closed; - } + static bool IsScannerClosed(const folly::exception_wrapper& exception); - static bool IsScannerOutOfOrder(const folly::exception_wrapper& exception) { - bool scanner_out_of_order = false; - exception.with_exception([&](const RemoteException& remote_ex) { - auto java_class = remote_ex.exception_class_name(); - if (java_class == kOutOfOrderScannerNextException || java_class == kScannerResetException) { - scanner_out_of_order = true; - } - }); - return scanner_out_of_order; - } + static bool IsScannerOutOfOrder(const folly::exception_wrapper& exception); }; } // namespace hbase