Return-Path: X-Original-To: apmail-tajo-commits-archive@minotaur.apache.org Delivered-To: apmail-tajo-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2958D11E54 for ; Wed, 9 Jul 2014 04:10:20 +0000 (UTC) Received: (qmail 90032 invoked by uid 500); 9 Jul 2014 04:10:20 -0000 Delivered-To: apmail-tajo-commits-archive@tajo.apache.org Received: (qmail 89947 invoked by uid 500); 9 Jul 2014 04:10:20 -0000 Mailing-List: contact commits-help@tajo.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tajo.apache.org Delivered-To: mailing list commits@tajo.apache.org Received: (qmail 88791 invoked by uid 99); 9 Jul 2014 04:10:19 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Jul 2014 04:10:19 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 4C5FA9A8C5F; Wed, 9 Jul 2014 04:10:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: hyunsik@apache.org To: commits@tajo.apache.org Date: Wed, 09 Jul 2014 04:10:44 -0000 Message-Id: <8e429249c7ff4a6e966e434193141e65@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [27/50] [abbrv] git commit: TAJO-882: CLI hangs when a error occurs in the GlobalPlanner. (Hyoungjun Kim via hyunsik) TAJO-882: CLI hangs when a error occurs in the GlobalPlanner. (Hyoungjun Kim via hyunsik) Closes #42 Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/dff6a307 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/dff6a307 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/dff6a307 Branch: refs/heads/window_function Commit: dff6a30740bb2348868ebd527ced0a48973bf45c Parents: 56d5daa Author: Hyunsik Choi Authored: Tue Jun 24 20:25:06 2014 +0900 Committer: Hyunsik Choi Committed: Tue Jun 24 20:25:37 2014 +0900 ---------------------------------------------------------------------- CHANGES | 3 ++ .../tajo/engine/planner/LogicalOptimizer.java | 19 ++++++-- .../utils/test/ErrorInjectionRewriter.java | 40 +++++++++++++++++ .../master/querymaster/QueryMasterTask.java | 4 ++ .../tajo/worker/TajoWorkerClientService.java | 9 ++++ .../org/apache/tajo/TajoTestingCluster.java | 4 ++ .../tajo/engine/query/TestSelectQuery.java | 46 +++++++++++++++++++- 7 files changed, 119 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 0bb38b2..3d2a531 100644 --- a/CHANGES +++ b/CHANGES @@ -74,6 +74,9 @@ Release 0.9.0 - unreleased BUG FIXES + TAJO-882: CLI hangs when a error occurs in the GlobalPlanner. + (Hyoungjun Kim via hyunsik) + TAJO-850: OUTER JOIN does not properly handle a NULL. (Hyoungjun Kim via hyunsik) http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalOptimizer.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalOptimizer.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalOptimizer.java index 0480fe9..3ffeeb0 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalOptimizer.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalOptimizer.java @@ -34,10 +34,7 @@ import org.apache.tajo.engine.planner.logical.join.FoundJoinOrder; import org.apache.tajo.engine.planner.logical.join.GreedyHeuristicJoinOrderAlgorithm; import org.apache.tajo.engine.planner.logical.join.JoinGraph; import org.apache.tajo.engine.planner.logical.join.JoinOrderAlgorithm; -import org.apache.tajo.engine.planner.rewrite.BasicQueryRewriteEngine; -import org.apache.tajo.engine.planner.rewrite.FilterPushDownRule; -import org.apache.tajo.engine.planner.rewrite.PartitionedTableRewriter; -import org.apache.tajo.engine.planner.rewrite.ProjectionPushDownRule; +import org.apache.tajo.engine.planner.rewrite.*; import org.apache.tajo.master.session.Session; import java.util.LinkedHashSet; @@ -67,6 +64,20 @@ public class LogicalOptimizer { rulesAfterToJoinOpt = new BasicQueryRewriteEngine(); rulesAfterToJoinOpt.addRewriteRule(new ProjectionPushDownRule()); rulesAfterToJoinOpt.addRewriteRule(new PartitionedTableRewriter(systemConf)); + + // Currently, it is only used for some test cases to inject exception manually. + String userDefinedRewriterClass = systemConf.get("tajo.plan.rewriter.classes"); + if (userDefinedRewriterClass != null && !userDefinedRewriterClass.isEmpty()) { + for (String eachRewriterClass : userDefinedRewriterClass.split(",")) { + try { + RewriteRule rule = (RewriteRule) Class.forName(eachRewriterClass).newInstance(); + rulesAfterToJoinOpt.addRewriteRule(rule); + } catch (Exception e) { + LOG.error("Can't initiate a Rewriter object: " + eachRewriterClass, e); + continue; + } + } + } } public LogicalNode optimize(LogicalPlan plan) throws PlanningException { http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/tajo-core/src/main/java/org/apache/tajo/engine/utils/test/ErrorInjectionRewriter.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/utils/test/ErrorInjectionRewriter.java b/tajo-core/src/main/java/org/apache/tajo/engine/utils/test/ErrorInjectionRewriter.java new file mode 100644 index 0000000..333df11 --- /dev/null +++ b/tajo-core/src/main/java/org/apache/tajo/engine/utils/test/ErrorInjectionRewriter.java @@ -0,0 +1,40 @@ +/** + * 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.tajo.engine.utils.test; + +import org.apache.tajo.engine.planner.LogicalPlan; +import org.apache.tajo.engine.planner.PlanningException; +import org.apache.tajo.engine.planner.rewrite.RewriteRule; + +public class ErrorInjectionRewriter implements RewriteRule { + @Override + public String getName() { + return "ErrorInjectionRewriter"; + } + + @Override + public boolean isEligible(LogicalPlan plan) { + return true; + } + + @Override + public LogicalPlan rewrite(LogicalPlan plan) throws PlanningException { + throw new NullPointerException(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/tajo-core/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java b/tajo-core/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java index 271864c..0061717 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java @@ -496,6 +496,10 @@ public class QueryMasterTask extends CompositeService { } } + public Throwable getInitError() { + return initError; + } + public String getErrorMessage() { if (isInitError()) { return StringUtils.stringifyException(initError); http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java b/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java index 2b947fe..abd4e98 100644 --- a/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/worker/TajoWorkerClientService.java @@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.service.AbstractService; +import org.apache.hadoop.util.StringUtils; import org.apache.tajo.QueryId; import org.apache.tajo.QueryIdFactory; import org.apache.tajo.TajoIdProtos; @@ -210,6 +211,14 @@ public class TajoWorkerClientService extends AbstractService { builder.setErrorMessage(firstError.getErrorMessage()); builder.setErrorTrace(firstError.getErrorTrace()); } + + if (queryMasterTask.isInitError()) { + Throwable initError = queryMasterTask.getInitError(); + builder.setErrorMessage( + initError.getMessage() == null ? initError.getClass().getName() : initError.getMessage()); + builder.setErrorTrace(StringUtils.stringifyException(initError)); + builder.setState(queryMasterTask.getState()); + } } return builder.build(); } http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java b/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java index 0237639..5cb98ba 100644 --- a/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java +++ b/tajo-core/src/test/java/org/apache/tajo/TajoTestingCluster.java @@ -641,6 +641,10 @@ public class TajoTestingCluster { public void setAllTajoDaemonConfValue(String key, String value) { tajoMaster.getContext().getConf().set(key, value); + setAllWorkersConfValue(key, value); + } + + public void setAllWorkersConfValue(String key, String value) { for (TajoWorker eachWorker: tajoWorkers) { eachWorker.getConfig().set(key, value); } http://git-wip-us.apache.org/repos/asf/tajo/blob/dff6a307/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java index 96c51fe..372c595 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java @@ -21,17 +21,20 @@ package org.apache.tajo.engine.query; import org.apache.tajo.IntegrationTest; import org.apache.tajo.QueryTestCaseBase; import org.apache.tajo.TajoConstants; +import org.apache.tajo.TajoProtos.QueryState; import org.apache.tajo.TajoTestingCluster; import org.apache.tajo.catalog.CatalogService; import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.client.QueryStatus; +import org.apache.tajo.engine.utils.test.ErrorInjectionRewriter; +import org.apache.tajo.jdbc.TajoResultSet; import org.junit.Test; import org.junit.experimental.categories.Category; import java.sql.ResultSet; import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; @Category(IntegrationTest.class) public class TestSelectQuery extends QueryTestCaseBase { @@ -303,6 +306,7 @@ public class TestSelectQuery extends QueryTestCaseBase { cleanupQuery(res); } + @Test public final void testDatabaseRef() throws Exception { if (!testingCluster.isHCatalogStoreRunning()) { executeString("CREATE DATABASE \"TestSelectQuery\"").close(); @@ -345,4 +349,42 @@ public class TestSelectQuery extends QueryTestCaseBase { assertResultSet(res); cleanupQuery(res); } + + @Test + public final void testQueryMasterTaskInitError() throws Exception { + // In this testcase we can check that a TajoClient receives QueryMasterTask's init error message. + testingCluster.setAllWorkersConfValue("tajo.plan.rewriter.classes", + ErrorInjectionRewriter.class.getCanonicalName()); + + try { + // If client can't receive error status, thread runs forever. + Thread t = new Thread() { + public void run() { + try { + TajoResultSet res = (TajoResultSet) client.executeQueryAndGetResult("select l_orderkey from lineitem"); + QueryStatus status = client.getQueryStatus(res.getQueryId()); + assertEquals(QueryState.QUERY_ERROR, status.getState()); + assertEquals(NullPointerException.class.getName(), status.getErrorMessage()); + cleanupQuery(res); + } catch (Exception e) { + fail(e.getMessage()); + } + } + }; + + t.start(); + + for (int i = 0; i < 10; i++) { + Thread.sleep(1 * 1000); + if (!t.isAlive()) { + break; + } + } + + // If query runs more than 10 secs, test is fail. + assertFalse(t.isAlive()); + } finally { + testingCluster.setAllWorkersConfValue("tajo.plan.rewriter.classes", ""); + } + } } \ No newline at end of file