diff --git a/service/src/java/org/apache/hive/service/cli/CLIService.java b/service/src/java/org/apache/hive/service/cli/CLIService.java index ed52b4a..662e55c 100644 --- a/service/src/java/org/apache/hive/service/cli/CLIService.java +++ b/service/src/java/org/apache/hive/service/cli/CLIService.java @@ -425,14 +425,19 @@ public OperationStatus getOperationStatus(OperationHandle opHandle) Operation operation = sessionManager.getOperationManager().getOperation(opHandle); /** * If this is a background operation run asynchronously, - * we block for a configured duration, before we return - * (duration: HIVE_SERVER2_LONG_POLLING_TIMEOUT). + * we block for a duration determined by a step function, before we return * However, if the background operation is complete, we return immediately. */ if (operation.shouldRunAsync()) { HiveConf conf = operation.getParentSession().getHiveConf(); - long timeout = HiveConf.getTimeVar(conf, + long maxTimeout = HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_SERVER2_LONG_POLLING_TIMEOUT, TimeUnit.MILLISECONDS); + + final long elapsed = System.currentTimeMillis() - operation.getBeginTime(); + // A step function to increase the polling timeout by 500 ms every 10 sec, + // starting from 500 ms up to HIVE_SERVER2_LONG_POLLING_TIMEOUT + final long timeout = Math.min(maxTimeout, (elapsed / TimeUnit.SECONDS.toMillis(10) + 1) * 500); + try { operation.getBackgroundHandle().get(timeout, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { diff --git a/service/src/test/org/apache/hive/service/cli/CLIServiceTest.java b/service/src/test/org/apache/hive/service/cli/CLIServiceTest.java index 17d45ec..237fcc0 100644 --- a/service/src/test/org/apache/hive/service/cli/CLIServiceTest.java +++ b/service/src/test/org/apache/hive/service/cli/CLIServiceTest.java @@ -528,14 +528,15 @@ private OperationStatus runAsyncAndWait(SessionHandle sessionHandle, String quer } private OperationStatus waitForAsyncQuery(OperationHandle opHandle, - OperationState expectedState, long longPollingTimeout) throws HiveSQLException { + OperationState expectedState, long maxLongPollingTimeout) throws HiveSQLException { long testIterationTimeout = System.currentTimeMillis() + 100000; long longPollingStart; long longPollingEnd; long longPollingTimeDelta; OperationStatus opStatus = null; OperationState state = null; - int count = 0; + int count = 0; + long start = System.currentTimeMillis(); while (true) { // Break if iteration times out if (System.currentTimeMillis() > testIterationTimeout) { @@ -560,8 +561,11 @@ private OperationStatus waitForAsyncQuery(OperationHandle opHandle, } else { // Verify that getOperationStatus returned only after the long polling timeout longPollingTimeDelta = longPollingEnd - longPollingStart; + // Calculate the expected timeout based on the elapsed time between waiting start time and polling start time + long elapsed = longPollingStart - start; + long expectedTimeout = Math.min(maxLongPollingTimeout, (elapsed / TimeUnit.SECONDS.toMillis(10) + 1) * 500); // Scale down by a factor of 0.9 to account for approximate values - assertTrue(longPollingTimeDelta - 0.9*longPollingTimeout > 0); + assertTrue(longPollingTimeDelta - 0.9*expectedTimeout > 0); } } assertEquals(expectedState, client.getOperationStatus(opHandle).getState());