Skip to content
Snippets Groups Projects
Commit 714e93fc authored by gmantele's avatar gmantele
Browse files

[TAP] Improve the abortion of queries, particularly during the UPLOAD phase.

Now, it is recommended to throw a DBCancelledException from any DBConnection
long processing. It is already done for the upload of a table, the execution
of an ADQL query and the setting of a whole TAP_SCHEMA. The flag
JDBCConnection#cancelled has now a bit different meaning: it is set even if
the Statement.cancel() fails so that any JDBCConnection function can see that
a cancellation has been requested.
parent 225c49e1
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,7 @@ package tap;
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -31,6 +31,7 @@ import adql.parser.ParseException;
import adql.query.ADQLQuery;
import tap.data.DataReadException;
import tap.data.TableIterator;
import tap.db.DBCancelledException;
import tap.db.DBConnection;
import tap.db.DBException;
import tap.formatter.OutputFormat;
......@@ -104,7 +105,7 @@ import uws.service.log.UWSLog.LogLevel;
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.1 (04/2016)
* @version 2.1 (04/2017)
*/
public class ADQLExecutor {
......@@ -267,7 +268,7 @@ public class ADQLExecutor {
* @since 2.1
*/
public final void cancelQuery(){
if (dbConn != null && progression == ExecutionProgression.EXECUTING_ADQL)
if (dbConn != null && (progression == ExecutionProgression.EXECUTING_ADQL || progression == ExecutionProgression.UPLOADING))
dbConn.cancel(true);
}
......@@ -382,6 +383,8 @@ public class ADQLExecutor {
endStep();
if (queryResult == null || thread.isInterrupted())
/* Note: 'queryResult == null' is for former version of the library
* ; now, a DBCancelledException should be thrown instead */
throw new InterruptedException();
// 4. WRITE RESULT:
......@@ -400,6 +403,9 @@ public class ADQLExecutor {
logger.logTAP(LogLevel.INFO, report, "END_EXEC", "ADQL query execution finished.", null);
return report;
}catch(DBCancelledException dce){
throw new InterruptedException();
}finally{
// Close the result if any:
if (queryResult != null){
......@@ -570,15 +576,15 @@ public class ADQLExecutor {
*
* @param adql The object representation of the ADQL query to execute.
*
* @return The result of the query,
* or NULL if the query execution has failed.
* @return The result of the query.
*
* @throws InterruptedException If the thread has been interrupted.
* @throws DBCancelledException If the inner DB connection has been canceled.
* @throws TAPException If the {@link DBConnection} has failed to deal with the given ADQL query.
*
* @see DBConnection#executeQuery(ADQLQuery)
*/
protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, TAPException{
protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, DBCancelledException, TAPException{
// Log the start of execution:
logger.logTAP(LogLevel.INFO, report, "START_DB_EXECUTION", "ADQL query: " + adql.toADQL().replaceAll("(\t|\r?\n)+", " "), null);
......@@ -590,16 +596,22 @@ public class ADQLExecutor {
dbConn.setFetchSize(service.getFetchSize()[0]);
}
// Execute the ADQL query:
TableIterator result = dbConn.executeQuery(adql);
try{
// Execute the ADQL query:
TableIterator result = dbConn.executeQuery(adql);
// Log the success or failure:
if (result == null)
logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query execution aborted after " + (System.currentTimeMillis() - startStep) + "ms!", null);
else
// If NULL, in a former version of the library, it means the query execution has been aborted:
if (result == null)
throw new DBCancelledException();
// Log the success:
logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query successfully executed in " + (System.currentTimeMillis() - startStep) + "ms!", null);
return result;
return result;
}catch(DBCancelledException dce){
logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query execution aborted after " + (System.currentTimeMillis() - startStep) + "ms!", null);
throw dce;
}
}
/**
......
package tap.db;
/*
* This file is part of TAPLibrary.
*
* TAPLibrary is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TAPLibrary is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2017 - Astronomisches Rechen Institut (ARI)
*/
/**
* Exception thrown when a processing of a {@link DBConnection} is cancelled.
*
* @author Gr&eacute;gory Mantelet (ARI)
* @version 2.1 (04/2017)
*/
public class DBCancelledException extends DBException {
private static final long serialVersionUID = 1L;
public DBCancelledException(){
super("DB interaction cancelled!");
}
public DBCancelledException(String message){
super(message);
}
public DBCancelledException(String message, String query){
super(message, query);
}
public DBCancelledException(Throwable cause){
super(cause);
}
public DBCancelledException(Throwable cause, String query){
super(cause, query);
}
public DBCancelledException(String message, Throwable cause){
super(message, cause);
}
public DBCancelledException(String message, Throwable cause, String query){
super(message, cause, query);
}
}
......@@ -45,7 +45,7 @@ import tap.metadata.TAPTable;
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.1 (03/2017)
* @version 2.1 (04/2017)
*/
public interface DBConnection {
......@@ -172,11 +172,12 @@ public interface DBConnection {
*
* @param metadata List of all schemas, tables, columns and foreign keys to insert in the TAP_SCHEMA.
*
* @throws DBCancelledException If {@link #cancel(boolean)} has been called during the processing.
* @throws DBException If any error occurs while updating the database.
*
* @since 2.0
*/
public void setTAPSchema(final TAPMetadata metadata) throws DBException;
public void setTAPSchema(final TAPMetadata metadata) throws DBCancelledException, DBException;
/**
* Add the defined and given table inside the TAP_UPLOAD schema.
......@@ -192,12 +193,13 @@ public interface DBConnection {
*
* @return <i>true</i> if the given table has been successfully added, <i>false</i> otherwise.
*
* @throws DBCancelledException If {@link #cancel(boolean)} has been called during the processing.
* @throws DBException If any error occurs while adding the table.
* @throws DataReadException If any error occurs while reading the given data (particularly if any limit - in byte or row - set in the TableIterator is reached).
*
* @since 2.0
*/
public boolean addUploadedTable(final TAPTable tableDef, final TableIterator data) throws DBException, DataReadException;
public boolean addUploadedTable(final TAPTable tableDef, final TableIterator data) throws DBCancelledException, DBException, DataReadException;
/**
* <p>Drop the specified uploaded table from the database.
......@@ -237,16 +239,17 @@ public interface DBConnection {
*
* @param adqlQuery ADQL query to execute.
*
* @return The table result or NULL if the query has been aborted.
* @return The table result.
*
* @throws DBException If any errors occurs while executing the query.
* @throws DBCancelledException If {@link #cancel(boolean)} has been called (i.e. query aborted) during the processing.
* @throws DBException If any errors occurs while executing the query.
*
* @since 2.0
*
* @see #endQuery()
* @see TableIterator#close()
*/
public TableIterator executeQuery(final ADQLQuery adqlQuery) throws DBException;
public TableIterator executeQuery(final ADQLQuery adqlQuery) throws DBCancelledException, DBException;
/**
* <p>Set the number of rows to fetch before searching/getting the following.
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment