Author: sunchao
Date: Thu Mar 26 16:38:33 2015
New Revision: 1669367

URL: http://svn.apache.org/r1669367
Log:
HIVE-9839 - HiveServer2 leaks OperationHandle on async queries which fail at 
compile phase (Nemon via Chao)

Added:
    
hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/
    
hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestHiveSessionImpl.java
Modified:
    
hive/trunk/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java

Added: 
hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestHiveSessionImpl.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestHiveSessionImpl.java?rev=1669367&view=auto
==============================================================================
--- 
hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestHiveSessionImpl.java
 (added)
+++ 
hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestHiveSessionImpl.java
 Thu Mar 26 16:38:33 2015
@@ -0,0 +1,95 @@
+/**
+ * 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.hive.service.cli.session;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hive.service.cli.HiveSQLException;
+import org.apache.hive.service.cli.OperationHandle;
+import org.apache.hive.service.cli.operation.ExecuteStatementOperation;
+import org.apache.hive.service.cli.operation.OperationManager;
+import org.apache.hive.service.cli.thrift.TProtocolVersion;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+public class TestHiveSessionImpl {
+  /**
+   * Verifying OperationManager.closeOperation(opHandle) is invoked when
+   * get HiveSQLException during sync query
+   * @throws HiveSQLException
+   */
+  @Test
+  public void testLeakOperationHandle() throws HiveSQLException {
+    //create HiveSessionImpl object
+    TProtocolVersion protocol = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V2;
+    String username = "";
+    String password = "";
+    HiveConf serverhiveConf = new HiveConf();
+    String ipAddress = null;
+    HiveSessionImpl session = new HiveSessionImpl(protocol, username, password,
+      serverhiveConf, ipAddress) {
+      @Override
+      protected synchronized void acquire(boolean userAccess) {
+      }
+
+      @Override
+      protected synchronized void release(boolean userAccess) {
+      }
+    };
+
+    //mock operationManager for session
+    OperationManager operationManager = Mockito.mock(OperationManager.class);
+    session.setOperationManager(operationManager);
+
+    //mock operation and opHandle for operationManager
+    ExecuteStatementOperation operation = 
Mockito.mock(ExecuteStatementOperation.class);
+    OperationHandle opHandle = Mockito.mock(OperationHandle.class);
+    Mockito.when(operation.getHandle()).thenReturn(opHandle);
+    Map<String, String> confOverlay = new HashMap<String, String>();
+    String hql = "drop table if exists table_not_exists";
+    Mockito.when(operationManager.newExecuteStatementOperation(session, hql, 
confOverlay,
+            true)).thenReturn(operation);
+
+    try {
+
+      //Running a normal async query with no exceptions,then no need to close 
opHandle
+      session.executeStatementAsync(hql, confOverlay);
+      Mockito.verify(operationManager, 
Mockito.times(0)).closeOperation(opHandle);
+
+      // Throw an HiveSqlException when do async calls
+      Mockito.doThrow(new HiveSQLException("Fail for clean up 
test")).when(operation).run();
+      session.executeStatementAsync(hql, confOverlay);
+      Assert.fail("HiveSqlException expected.");
+
+    } catch (HiveSQLException e) {
+      if (!"Fail for clean up test".equals(e.getMessage())) {
+        Assert.fail("unexpected exception:" + e.getMessage());
+      }
+      //operationManager.closeOperation() is expected to be invoked once
+      Mockito.verify(operationManager, 
Mockito.times(1)).closeOperation(opHandle);
+    }
+  }
+
+}
+

Modified: 
hive/trunk/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java?rev=1669367&r1=1669366&r2=1669367&view=diff
==============================================================================
--- 
hive/trunk/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java
 (original)
+++ 
hive/trunk/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java
 Thu Mar 26 16:38:33 2015
@@ -382,11 +382,10 @@ public class HiveSessionImpl implements
       opHandleSet.add(opHandle);
       return opHandle;
     } catch (HiveSQLException e) {
-      // Cleanup opHandle in case the query is synchronous
-      // Async query needs to retain and pass back the opHandle for error 
reporting
-      if (!runAsync) {
-        operationManager.closeOperation(opHandle);
-      }
+      // Refering to SQLOperation.java,there is no chance that a 
HiveSQLException throws and the asyn
+      // background operation submits to thread pool successfully at the same 
time. So, Cleanup
+      // opHandle directly when got HiveSQLException
+      operationManager.closeOperation(opHandle);
       throw e;
     } finally {
       release(true);


Reply via email to