You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by am...@apache.org on 2016/05/12 04:38:24 UTC

lens git commit: LENS-1032 : Add option to kill the query on timeout api upon timeout

Repository: lens
Updated Branches:
  refs/heads/master 382881940 -> 389daac9a


LENS-1032 : Add option to kill the query on timeout api upon timeout


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/389daac9
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/389daac9
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/389daac9

Branch: refs/heads/master
Commit: 389daac9a66b0cb69ac729a56b39b3aa903ad36a
Parents: 3828819
Author: Puneet Gupta <pu...@gmail.com>
Authored: Thu May 12 10:08:11 2016 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Thu May 12 10:08:11 2016 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryStatus.java  |   8 ++
 .../src/main/resources/lens-client-default.xml  |   7 ++
 .../org/apache/lens/driver/hive/HiveDriver.java |   3 +
 .../lens/server/api/LensConfConstants.java      |  11 ++
 .../server/query/QueryExecutionServiceImpl.java | 120 +++++++++++++++----
 .../lens/server/query/QueryServiceResource.java |   6 +-
 .../src/main/resources/lenssession-default.xml  |   8 ++
 .../lens/server/query/TestQueryService.java     |  36 +++++-
 src/site/apt/admin/session-config.apt           |  58 ++++-----
 9 files changed, 201 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
index 67d1e79..daedbf9 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
@@ -205,6 +205,14 @@ public class QueryStatus extends ToYAMLString implements Serializable {
     return status.equals(Status.FAILED);
   }
 
+  public boolean cancelled() {
+    return status.equals(Status.CANCELED);
+  }
+
+  public boolean executed() {
+    return status.equals(Status.EXECUTED);
+  }
+
 
   /**
    * Checks if is valid transition.

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-client/src/main/resources/lens-client-default.xml
----------------------------------------------------------------------
diff --git a/lens-client/src/main/resources/lens-client-default.xml b/lens-client/src/main/resources/lens-client-default.xml
index 96506ac..132e1b1 100644
--- a/lens-client/src/main/resources/lens-client-default.xml
+++ b/lens-client/src/main/resources/lens-client-default.xml
@@ -75,4 +75,11 @@
     is used to execute a query. The default value is 10 seconds.
     </description>
   </property>
+  <property>
+    <name>lens.query.cancel.on.timeout</name>
+    <value>false</value>
+    <description>Specifies whether to attempt cancellation of a query whose execution takes longer than the timeout
+      value specified while submitting the query for execution.
+    </description>
+  </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
----------------------------------------------------------------------
diff --git a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
index 1463cc2..b85a66f 100644
--- a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
+++ b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
@@ -1048,6 +1048,9 @@ public class HiveDriver extends AbstractLensDriver {
       this.timeoutMillis = timeoutMillis;
       this.listener = listener;
       this.pollInterval = timeoutMillis / 10;
+      if (pollInterval < 5000) {
+        pollInterval = 5000; //minimum poll interval is 5 secs
+      }
     }
 
     /*

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
index 7cf6449..a6df138 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
@@ -1070,4 +1070,15 @@ public final class LensConfConstants {
    * Default value of DEFAULT_STATUS_UPDATE_EXPONENTIAL_WAIT_FACTOR is 30000 millis (30 seconds)
    */
   public static final long DEFAULT_STATUS_UPDATE_EXPONENTIAL_WAIT_FACTOR = 30000;
+
+  /**
+   * Specifies whether to attempt cancellation of a query whose execution takes longer than the timeout value
+   * specified while submitting the query for execution.
+   */
+  public static final String CANCEL_QUERY_ON_TIMEOUT = QUERY_PFX + "cancel.on.timeout";
+
+  /**
+   * Default value of "lens.query.cancel.on.timeout"
+   */
+  public static final boolean DEFAULT_CANCEL_QUERY_ON_TIMEOUT = true;
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index b12943e..97cab86 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -77,6 +77,7 @@ import org.apache.lens.server.util.UtilityMethods;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FSDataInputStream;
 import org.apache.hadoop.fs.FileSystem;
@@ -256,6 +257,11 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    */
   private ExecutorService estimatePool;
 
+  /**
+   * The pool used for cancelling timed out queries.
+   */
+  private ExecutorService queryCancellationPool;
+
   private final LogSegregationContext logSegregationContext;
 
   private final ErrorCollection errorCollection = LensServices.get().getErrorCollection();
@@ -1245,6 +1251,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       queryResultPurger.stop();
     }
 
+    queryCancellationPool.shutdown();
+
     log.info("Query execution service stopped");
   }
 
@@ -1281,6 +1289,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     prepareQueryPurger.start();
 
     startEstimatePool();
+    startQueryCancellationPool();
 
     if (conf.getBoolean(RESULTSET_PURGE_ENABLED, DEFAULT_RESULTSET_PURGE_ENABLED)) {
       queryResultPurger = new QueryResultPurger();
@@ -1319,6 +1328,28 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     this.estimatePool = estimatePool;
   }
 
+  private void startQueryCancellationPool() {
+    ThreadFactory factory = new BasicThreadFactory.Builder()
+      .namingPattern("query-cancellation-pool-Thread-%d")
+      .priority(Thread.NORM_PRIORITY)
+      .build();
+    //Using fixed values for pool . corePoolSize = maximumPoolSize = 3  and keepAliveTime = 60 secs
+    queryCancellationPool = new ThreadPoolExecutor(3, 3, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(), factory);
+  }
+
+  @AllArgsConstructor
+  private class CancelQueryTask implements Runnable {
+    private QueryHandle handle;
+    @Override
+    public void run() {
+      try {
+        cancelQuery(handle);
+      } catch (Exception e) {
+        log.error("Error while cancelling query {}", handle, e);
+      }
+    }
+  }
+
   private static final String REWRITE_GAUGE = "CUBE_REWRITE";
   private static final String DRIVER_ESTIMATE_GAUGE = "DRIVER_ESTIMATE";
   private static final String DRIVER_SELECTOR_GAUGE = "DRIVER_SELECTION";
@@ -2028,26 +2059,35 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     long timeOutTime = System.currentTimeMillis() + timeoutMillis;
     QueryHandleWithResultSet result = new QueryHandleWithResultSet(handle);
 
-    while (isQueued(sessionHandle, handle)) {
+    boolean isQueued = true;
+    while (isQueued && System.currentTimeMillis() < timeOutTime) {
       try {
         Thread.sleep(10);
+        isQueued = isQueued(sessionHandle, handle);
       } catch (InterruptedException e) {
         log.error("Encountered Interrupted exception.", e);
       }
     }
+    if (isQueued) { //query is still queued even after waiting for timeoutMillis
+      result.setStatus(ctx.getStatus());
+      addQueryToCancellationPool(ctx, conf, timeoutMillis); //cancel the timed-out Query
+      return result;
+    }
 
     QueryContext queryCtx = getUpdatedQueryContext(sessionHandle, handle);
     if (queryCtx.getSelectedDriver() == null) {
       result.setStatus(queryCtx.getStatus());
       return result;
     }
+
     QueryCompletionListenerImpl listener = new QueryCompletionListenerImpl(handle);
-    synchronized (queryCtx) {
-      if (!queryCtx.getStatus().finished()) {
-        queryCtx.getSelectedDriver().registerForCompletionNotification(handle, timeoutMillis, listener);
+    long waitTime = timeOutTime - System.currentTimeMillis();
+    if (waitTime > 0 && !queryCtx.getStatus().finished()) {
+      synchronized (queryCtx) {
+        queryCtx.getSelectedDriver().registerForCompletionNotification(handle, waitTime, listener);
         try {
           synchronized (listener) {
-            listener.wait(timeoutMillis);
+            listener.wait(waitTime);
           }
         } catch (InterruptedException e) {
           log.info("Waiting thread interrupted");
@@ -2055,11 +2095,13 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       }
     }
 
+
+
     // At this stage (since the listener waits only for driver completion and not server that may include result
     // formatting and persistence) the query status can be RUNNING or EXECUTED or FAILED or SUCCESSFUL
     LensResultSet resultSet = null;
     queryCtx = getUpdatedQueryContext(sessionHandle, handle, true); // If the query is already purged queryCtx = null
-    if (queryCtx != null && listener.querySuccessful && queryCtx.getStatus().isResultSetAvailable()) {
+    if (queryCtx != null && queryCtx.getStatus().isResultSetAvailable()) {
       resultSet = queryCtx.getSelectedDriver().fetchResultSet(queryCtx);
       if (resultSet instanceof PartiallyFetchedInMemoryResultSet) {
         PartiallyFetchedInMemoryResultSet partialnMemoryResult = (PartiallyFetchedInMemoryResultSet) resultSet;
@@ -2095,9 +2137,27 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     result.setResult(null);
     result.setResultMetadata(null);
     result.setStatus(queryCtx.getStatus());
+
+    if (!queryCtx.finished()) {
+      addQueryToCancellationPool(queryCtx, conf, timeoutMillis); //cancel the timed-out Query
+    }
+
     return result;
   }
 
+  /**
+   * This method is used to add a timed out query to cancellation pool.
+   * The query gets cancelled asynchronously
+   * Note : lens.query.cancel.on.timeout should be true for cancellation
+   */
+  private void addQueryToCancellationPool(QueryContext queryCtx, Configuration config, long timeoutMillis) {
+    if (config.getBoolean(CANCEL_QUERY_ON_TIMEOUT, DEFAULT_CANCEL_QUERY_ON_TIMEOUT)) {
+      log.info("Query {} will be cancelled as it could not be completed within the specified timeout interval {}",
+        queryCtx.getQueryHandle(), timeoutMillis);
+      queryCancellationPool.submit(new CancelQueryTask(queryCtx.getQueryHandle()));
+    }
+  }
+
   private boolean isQueued(final LensSessionHandle sessionHandle, final QueryHandle handle)
     throws LensException {
     // getQueryContext calls updateStatus, which fires query events if there's a change in status
@@ -2239,26 +2299,38 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     try {
       log.info("CancelQuery: session:{} query:{}", sessionHandle, queryHandle);
       acquire(sessionHandle);
-      QueryContext ctx = getUpdatedQueryContext(sessionHandle, queryHandle);
+      return cancelQuery(queryHandle);
+    } finally {
+      release(sessionHandle);
+    }
+  }
 
-      synchronized (ctx) {
+  private boolean cancelQuery(@NonNull QueryHandle queryHandle) throws LensException {
+    QueryContext ctx =  allQueries.get(queryHandle);
+    if (ctx == null) {
+      log.info("Could not cancel query {} as it has been purged already", queryHandle);
+      return false;
+    }
 
-        if (ctx.finished()) {
-          return false;
-        }
+    synchronized (ctx) {
 
-        if (ctx.launched() || ctx.running()) {
-          boolean ret = ctx.getSelectedDriver().cancelQuery(queryHandle);
-          if (!ret) {
-            return false;
-          }
-        }
+      updateStatus(queryHandle);
 
-        setCancelledStatus(ctx, "Query is cancelled");
-        return true;
+      if (ctx.finished()) {
+        log.info("Could not cancel query {} as it has finished execution already", queryHandle);
+        return false;
       }
-    } finally {
-      release(sessionHandle);
+
+      if (ctx.launched() || ctx.running()) {
+        if (!ctx.getSelectedDriver().cancelQuery(queryHandle)) {
+          log.info("Could not cancel query {}", queryHandle);
+          return false;
+        }
+      }
+
+      log.info("Query {} cancelled successfully", queryHandle);
+      setCancelledStatus(ctx, "Query is cancelled");
+      return true;
     }
   }
 
@@ -2681,6 +2753,12 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       details.append("QueryResultPurger is dead.");
     }
 
+    if (queryCancellationPool.isShutdown() || queryCancellationPool.isTerminated()) {
+      isHealthy = false;
+      details.append("Query Cancellation Pool is dead.");
+    }
+
+
     if (!isHealthy) {
       log.error(details.toString());
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
index a043550..d384abc 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
@@ -191,7 +191,11 @@ public class QueryServiceResource {
    *                      {@link org.apache.lens.api.query.SubmitOp#EXECUTE} and
    *                      {@link org.apache.lens.api.query.SubmitOp#EXECUTE_WITH_TIMEOUT}
    * @param conf          The configuration for the query
-   * @param timeoutmillis The timeout for the query, honored only in case of value {@link
+   * @param timeoutmillis The timeout for the query. If the query does not finish within the specified
+   *                      timeout, it is automatically cancelled unless user specified otherwise
+   *                      by setting configuration lens.query.cancel.on.timeout = false.
+   *                      <br>
+   *                      Note: The timeout parameter is honored only in case of {@link
    *                      org.apache.lens.api.query.SubmitOp#EXECUTE_WITH_TIMEOUT} operation
    * @param queryName     human readable query name set by user (optional parameter)
 

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-server/src/main/resources/lenssession-default.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/main/resources/lenssession-default.xml b/lens-server/src/main/resources/lenssession-default.xml
index ce296cc..62fca51 100644
--- a/lens-server/src/main/resources/lenssession-default.xml
+++ b/lens-server/src/main/resources/lenssession-default.xml
@@ -234,6 +234,14 @@
     </description>
   </property>
 
+  <property>
+    <name>lens.query.cancel.on.timeout</name>
+    <value>true</value>
+    <description>Specifies whether to attempt cancellation of a query whose execution takes longer than the timeout
+    value specified while submitting the query for execution. The default value is true.
+    </description>
+  </property>
+
   <!--  properties for session -->
   <property>
     <name>lens.session.aux.jars</name>

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
index 62c0280..164c9f8 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
@@ -18,6 +18,7 @@
  */
 package org.apache.lens.server.query;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
 import static javax.ws.rs.core.Response.Status.*;
 
 import static org.apache.lens.server.LensServerTestUtil.DB_WITH_JARS;
@@ -1257,7 +1258,7 @@ public class TestQueryService extends LensJerseyTest {
   @Test(dataProvider = "mediaTypeData")
   public void testExecuteWithTimeoutQuery(MediaType mt) throws IOException, InterruptedException {
     final WebTarget target = target().path("queryapi/queries");
-
+    //1. Validate Persistent result
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
       mt));
@@ -1275,6 +1276,7 @@ public class TestQueryService extends LensJerseyTest {
     assertNotNull(result.getResult());
     validatePersistentResult((PersistentQueryResult) result.getResult(), result.getQueryHandle(), true, false);
 
+    //2. Validate InMemory result
     final FormDataMultiPart mp2 = new FormDataMultiPart();
     LensConf conf = new LensConf();
     conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "false");
@@ -1291,6 +1293,27 @@ public class TestQueryService extends LensJerseyTest {
     validateInmemoryResultForTimeoutQuery(target, mp2, mt);
   }
 
+  @Test
+  public void testAutoCancelOnTimeOut() throws Exception {
+    queryService.pauseQuerySubmitter(true);
+    //First query will not be queued. @see QueryExecutionServiceImpl.QuerySubmitter.run
+    queryService.executeAsync(lensSessionId, "select 1 from "+TEST_TABLE, new LensConf(), "dummyQuery");
+
+    //Second query after pause will be queued
+    QueryHandleWithResultSet result = queryService.execute(lensSessionId, "select ID, IDSTR from "+ TEST_TABLE, 100,
+      new LensConf(),  "testQuery");
+    assertNotNull(result.getQueryHandle());
+    assertTrue(result.getStatus().queued());
+    int checkCtr = 0;
+    boolean cancelled = false;
+    while (!cancelled && checkCtr++ < 100) { //Max 10 secs wait
+      Thread.sleep(100); //wait for query to get auto cancelled
+      cancelled = queryService.getUpdatedQueryContext(lensSessionId, result.getQueryHandle()).getStatus().cancelled();
+    }
+    assertTrue(cancelled); //auto cancelled beyond timeout
+    queryService.pauseQuerySubmitter(false);
+  }
+
   private void validateInmemoryResultForTimeoutQuery(WebTarget target, FormDataMultiPart mp, MediaType mt) {
     if (mt.equals(MediaType.APPLICATION_JSON_TYPE)) {
       String result = target.request(mt).post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), String.class);
@@ -1338,7 +1361,7 @@ public class TestQueryService extends LensJerseyTest {
 
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-        MediaType.APPLICATION_XML_TYPE));
+        APPLICATION_XML_TYPE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select ID, IDSTR from "
         + TEST_TABLE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "execute_with_timeout"));
@@ -1346,14 +1369,15 @@ public class TestQueryService extends LensJerseyTest {
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("timeoutmillis").build(), timeOutMillis + ""));
     LensConf conf = new LensConf();
     conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_SET, "true");
+    conf.addProperty(LensConfConstants.CANCEL_QUERY_ON_TIMEOUT, "false");
     conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "false");
     conf.addProperty(LensConfConstants.PREFETCH_INMEMORY_RESULTSET, "true");
     conf.addProperty(LensConfConstants.PREFETCH_INMEMORY_RESULTSET_ROWS, preFetchRows);
     conf.addProperty(LensConfConstants.QUERY_OUTPUT_FORMATTER, DeferredInMemoryResultFormatter.class.getName());
     conf.addProperty("deferPersistenceByMillis", deferPersistenceByMillis); // property used for test only
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), conf,
-        MediaType.APPLICATION_XML_TYPE));
-    QueryHandleWithResultSet result =target.request(MediaType.APPLICATION_XML_TYPE)
+        APPLICATION_XML_TYPE));
+    QueryHandleWithResultSet result =target.request(APPLICATION_XML_TYPE)
             .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
                 new GenericType<LensAPIResult<QueryHandleWithResultSet>>() {}).getData();
     QueryHandle handle = result.getQueryHandle();
@@ -1374,11 +1398,11 @@ public class TestQueryService extends LensJerseyTest {
       assertNull(result.getResult()); // Query execution not finished yet
     }
 
-    waitForQueryToFinish(target(), lensSessionId, handle, Status.SUCCESSFUL, MediaType.APPLICATION_XML_TYPE);
+    waitForQueryToFinish(target(), lensSessionId, handle, Status.SUCCESSFUL, APPLICATION_XML_TYPE);
 
     // Test Persistent Result
     validatePersistedResult(handle, target(), lensSessionId, new String[][] { { "ID", "INT" }, { "IDSTR", "STRING" } },
-        false, true, MediaType.APPLICATION_XML_TYPE);
+        false, true, APPLICATION_XML_TYPE);
   }
 
   public static class DeferredInMemoryResultFormatter extends FileSerdeFormatter {

http://git-wip-us.apache.org/repos/asf/lens/blob/389daac9/src/site/apt/admin/session-config.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/admin/session-config.apt b/src/site/apt/admin/session-config.apt
index 206d6a4..fc6916f 100644
--- a/src/site/apt/admin/session-config.apt
+++ b/src/site/apt/admin/session-config.apt
@@ -48,60 +48,62 @@ Lens session configuration
 *--+--+---+--+
 |12|lens.query.add.insert.overwrite|true|Prefix query with insert overwrite clause if the query is persistent. User can disable if user gave the clause himself.|
 *--+--+---+--+
-|13|lens.query.enable.mail.notify|false|When a query ends, whether to notify the submitter by mail or not.|
+|13|lens.query.cancel.on.timeout|true|Specifies whether to attempt cancellation of a query whose execution takes longer than the timeout value specified while submitting the query for execution. The default value is true.|
 *--+--+---+--+
-|14|lens.query.enable.metrics.per.query|false|Generates gauge metrics for each query to measure time taken with unique id appended for each query. Should be enabled only for performance measurements. Should not be enabled in day to day production environment.|
+|14|lens.query.enable.mail.notify|false|When a query ends, whether to notify the submitter by mail or not.|
 *--+--+---+--+
-|15|lens.query.enable.persistent.resultset|false|Whether to enable persistent resultset for queries. When enabled, server will fetch results from driver, custom format them if any and store in a configured location. The file name of query output is queryhandle-id, with configured extensions|
+|15|lens.query.enable.metrics.per.query|false|Generates gauge metrics for each query to measure time taken with unique id appended for each query. Should be enabled only for performance measurements. Should not be enabled in day to day production environment.|
 *--+--+---+--+
-|16|lens.query.enable.persistent.resultset.indriver|true|Whether the result should be persisted by driver. Currently only HiveDriver persists the results in a HDFS location.|
+|16|lens.query.enable.persistent.resultset|false|Whether to enable persistent resultset for queries. When enabled, server will fetch results from driver, custom format them if any and store in a configured location. The file name of query output is queryhandle-id, with configured extensions|
 *--+--+---+--+
-|17|lens.query.hdfs.output.path|hdfsout|The directory under the parent result directory, in which HiveDriver will persist the results, if persisting by driver is enabled. This directory should exist and should have world writable permissions sothat all users will be able put query outputs here.|
+|17|lens.query.enable.persistent.resultset.indriver|true|Whether the result should be persisted by driver. Currently only HiveDriver persists the results in a HDFS location.|
 *--+--+---+--+
-|18|lens.query.output.charset.encoding|UTF-8|The charset encoding for formatting query result. It supports all the encodings supported by java.io.OutputStreamWriter.|
+|18|lens.query.hdfs.output.path|hdfsout|The directory under the parent result directory, in which HiveDriver will persist the results, if persisting by driver is enabled. This directory should exist and should have world writable permissions sothat all users will be able put query outputs here.|
 *--+--+---+--+
-|19|lens.query.output.compression.codec|org.apache.hadoop.io.compress.GzipCodec|The codec used to compress the query output, if compression is enabled|
+|19|lens.query.output.charset.encoding|UTF-8|The charset encoding for formatting query result. It supports all the encodings supported by java.io.OutputStreamWriter.|
 *--+--+---+--+
-|20|lens.query.output.enable.compression|false|Whether to compress the query result output|
+|20|lens.query.output.compression.codec|org.apache.hadoop.io.compress.GzipCodec|The codec used to compress the query output, if compression is enabled|
 *--+--+---+--+
-|21|lens.query.output.file.extn|.csv|The extension name for the persisted query output file. If file is compressed, the extension from compression codec will be appended to this extension.|
+|21|lens.query.output.enable.compression|false|Whether to compress the query result output|
 *--+--+---+--+
-|22|lens.query.output.footer| |The value of custom footer that should be written, if any. This footer will be added in formatting driver persisted results.|
+|22|lens.query.output.file.extn|.csv|The extension name for the persisted query output file. If file is compressed, the extension from compression codec will be appended to this extension.|
 *--+--+---+--+
-|23|lens.query.output.formatter| |The query result output formatter for the query. If no value is specified, then org.apache.lens.lib.query.FileSerdeFormatter will be used to format in-memory result sets, org.apache.lens.lib.query.FilePersistentFormatter will be used to format driver persisted result sets.|
+|23|lens.query.output.footer| |The value of custom footer that should be written, if any. This footer will be added in formatting driver persisted results.|
 *--+--+---+--+
-|24|lens.query.output.header| |The value of custom header that should be written, if any. If no value column names will be used as header.|
+|24|lens.query.output.formatter| |The query result output formatter for the query. If no value is specified, then org.apache.lens.lib.query.FileSerdeFormatter will be used to format in-memory result sets, org.apache.lens.lib.query.FilePersistentFormatter will be used to format driver persisted result sets.|
 *--+--+---+--+
-|25|lens.query.output.write.footer|false|Whether to write footer as part of query result. When enabled, total number of rows will be written as part of header.|
+|25|lens.query.output.header| |The value of custom header that should be written, if any. If no value column names will be used as header.|
 *--+--+---+--+
-|26|lens.query.output.write.header|false|Whether to write header as part of query result formatting. When enabled the user given header will be added in case of driver persisted results, and column names chosen will be added as header for in-memory results.|
+|26|lens.query.output.write.footer|false|Whether to write footer as part of query result. When enabled, total number of rows will be written as part of header.|
 *--+--+---+--+
-|27|lens.query.prefetch.inmemory.resultset|true|When set to true, specified number of rows of result set will be pre-fetched if the result set is of type InMemoryResultSet and query execution is not asynchronous i.e. query should be launched with operation as EXECUTE_WITH_TIMEOUT. Suggested usage of this property: It can be used by client to stream as well as persist results in server for queries that finish fast and produce results with fewer rows (should be less than number of rows pre-fetched). Note that the results are streamed to the client early, without waiting for persistence to finish. Default value of this property is true.|
+|27|lens.query.output.write.header|false|Whether to write header as part of query result formatting. When enabled the user given header will be added in case of driver persisted results, and column names chosen will be added as header for in-memory results.|
 *--+--+---+--+
-|28|lens.query.prefetch.inmemory.resultset.rows|100|Specifies the number of rows to pre-fetch when lens.query.prefetch.inmemory.resultset is set to true. Default value is 100 rows.|
+|28|lens.query.prefetch.inmemory.resultset|true|When set to true, specified number of rows of result set will be pre-fetched if the result set is of type InMemoryResultSet and query execution is not asynchronous i.e. query should be launched with operation as EXECUTE_WITH_TIMEOUT. Suggested usage of this property: It can be used by client to stream as well as persist results in server for queries that finish fast and produce results with fewer rows (should be less than number of rows pre-fetched). Note that the results are streamed to the client early, without waiting for persistence to finish. Default value of this property is true.|
 *--+--+---+--+
-|29|lens.query.result.email.cc| |When query ends, the result/failure reason will be sent to the user via email. The mail would be cc'ed to the addresses provided in this field.|
+|29|lens.query.prefetch.inmemory.resultset.rows|100|Specifies the number of rows to pre-fetch when lens.query.prefetch.inmemory.resultset is set to true. Default value is 100 rows.|
 *--+--+---+--+
-|30|lens.query.result.fs.read.url| |Http read URL for FileSystem on which result is present, if available. For example webhdfs as http read url should http://host:port/webhdfs/v1. Currently we support only webhdfs url as the http url for HDFS file system|
+|30|lens.query.result.email.cc| |When query ends, the result/failure reason will be sent to the user via email. The mail would be cc'ed to the addresses provided in this field.|
 *--+--+---+--+
-|31|lens.query.result.output.dir.format| |The format of the output if result is persisted in hdfs. The format should be expressed in HQL.|
+|31|lens.query.result.fs.read.url| |Http read URL for FileSystem on which result is present, if available. For example webhdfs as http read url should http://host:port/webhdfs/v1. Currently we support only webhdfs url as the http url for HDFS file system|
 *--+--+---+--+
-|32|lens.query.result.output.serde|org.apache.lens.lib.query.CSVSerde|The default serde class name that should be used by org.apache.lens.lib.query.FileSerdeFormatter for formatting the output|
+|32|lens.query.result.output.dir.format| |The format of the output if result is persisted in hdfs. The format should be expressed in HQL.|
 *--+--+---+--+
-|33|lens.query.result.parent.dir|file:///tmp/lensreports|The directory for storing persisted result of query. This directory should exist and should have writable permissions by lens server|
+|33|lens.query.result.output.serde|org.apache.lens.lib.query.CSVSerde|The default serde class name that should be used by org.apache.lens.lib.query.FileSerdeFormatter for formatting the output|
 *--+--+---+--+
-|34|lens.query.result.size.format.threshold|10737418240|The maximum allowed size of the query result. If exceeds, no server side formatting would be done.|
+|34|lens.query.result.parent.dir|file:///tmp/lensreports|The directory for storing persisted result of query. This directory should exist and should have writable permissions by lens server|
 *--+--+---+--+
-|35|lens.query.result.split.multiple|false|Whether to split the result into multiple files. If enabled, each file will be restricted to max rows configured. All the files will be available as zip.|
+|35|lens.query.result.size.format.threshold|10737418240|The maximum allowed size of the query result. If exceeds, no server side formatting would be done.|
 *--+--+---+--+
-|36|lens.query.result.split.multiple.maxrows|100000|The maximum number of rows allowed in each file, when splitting the result into multiple files is enabled.|
+|36|lens.query.result.split.multiple|false|Whether to split the result into multiple files. If enabled, each file will be restricted to max rows configured. All the files will be available as zip.|
 *--+--+---+--+
-|37|lens.session.aux.jars| |List of comma separated jar paths, which will added to the session|
+|37|lens.query.result.split.multiple.maxrows|100000|The maximum number of rows allowed in each file, when splitting the result into multiple files is enabled.|
 *--+--+---+--+
-|38|lens.session.cluster.user| |Session level config which will determine which cluster user will access hdfs|
+|38|lens.session.aux.jars| |List of comma separated jar paths, which will added to the session|
 *--+--+---+--+
-|39|lens.session.loggedin.user| |The username used to log in to lens. e.g. LDAP user|
+|39|lens.session.cluster.user| |Session level config which will determine which cluster user will access hdfs|
 *--+--+---+--+
-|40|lens.session.metastore.exclude.cubetables.from.nativetables|true|Exclude cube related tables when fetching native tables|
+|40|lens.session.loggedin.user| |The username used to log in to lens. e.g. LDAP user|
+*--+--+---+--+
+|41|lens.session.metastore.exclude.cubetables.from.nativetables|true|Exclude cube related tables when fetching native tables|
 *--+--+---+--+
 The configuration parameters and their default values