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
Loading
Loading
Loading
Loading
+25 −13
Original line number Diff line number Diff line
@@ -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]);
		}

		try{
			// Execute the ADQL query:
			TableIterator result = dbConn.executeQuery(adql);

		// Log the success or failure:
			// If NULL, in a former version of the library, it means the query execution has been aborted:
			if (result == null)
			logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query execution aborted after " + (System.currentTimeMillis() - startStep) + "ms!", null);
		else
				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;
		}catch(DBCancelledException dce){
			logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query execution aborted after " + (System.currentTimeMillis() - startStep) + "ms!", null);
			throw dce;
		}
	}

	/**
+59 −0
Original line number Diff line number Diff line
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);
	}

}
+9 −6
Original line number Diff line number Diff line
@@ -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,8 +239,9 @@ 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 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
@@ -246,7 +249,7 @@ public interface DBConnection {
	 * @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.
+167 −76

File changed.

Preview size limit exceeded, changes collapsed.