From 35827e47cc47ccb40335feb29cbd28de593c8344 Mon Sep 17 00:00:00 2001 From: gmantele <gmantele@ari.uni-heidelberg.de> Date: Mon, 9 Feb 2015 15:42:11 +0100 Subject: [PATCH] [TAP] Add a parameter to limit the number of running asynchronous jobs in the configuration file: max_async_jobs. --- src/tap/config/DefaultServiceConnection.java | 27 ++++++++++--- src/tap/config/TAPConfiguration.java | 4 ++ src/tap/config/tap_configuration_file.html | 13 ++++++ src/tap/config/tap_full.properties | 40 +++++-------------- .../config/TestDefaultServiceConnection.java | 40 ++++++++++++++++++- 5 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/tap/config/DefaultServiceConnection.java b/src/tap/config/DefaultServiceConnection.java index c6598a0..c6aa84c 100644 --- a/src/tap/config/DefaultServiceConnection.java +++ b/src/tap/config/DefaultServiceConnection.java @@ -3,6 +3,7 @@ package tap.config; import static tap.config.TAPConfiguration.DEFAULT_DIRECTORY_PER_USER; import static tap.config.TAPConfiguration.DEFAULT_EXECUTION_DURATION; import static tap.config.TAPConfiguration.DEFAULT_GROUP_USER_DIRECTORIES; +import static tap.config.TAPConfiguration.DEFAULT_MAX_ASYNC_JOBS; import static tap.config.TAPConfiguration.DEFAULT_RETENTION_PERIOD; import static tap.config.TAPConfiguration.DEFAULT_UPLOAD_MAX_FILE_SIZE; import static tap.config.TAPConfiguration.KEY_DEFAULT_EXECUTION_DURATION; @@ -13,6 +14,7 @@ import static tap.config.TAPConfiguration.KEY_DIRECTORY_PER_USER; import static tap.config.TAPConfiguration.KEY_FILE_MANAGER; import static tap.config.TAPConfiguration.KEY_FILE_ROOT_PATH; import static tap.config.TAPConfiguration.KEY_GROUP_USER_DIRECTORIES; +import static tap.config.TAPConfiguration.KEY_MAX_ASYNC_JOBS; import static tap.config.TAPConfiguration.KEY_MAX_EXECUTION_DURATION; import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT; import static tap.config.TAPConfiguration.KEY_MAX_RETENTION_PERIOD; @@ -77,6 +79,8 @@ public final class DefaultServiceConnection implements ServiceConnection { private boolean isAvailable = false; // the TAP service must be disabled until the end of its connection initialization private String availability = "TAP service not yet initialized."; + private int maxAsyncJobs = DEFAULT_MAX_ASYNC_JOBS; + private int[] executionDuration = new int[2]; private int[] retentionPeriod = new int[2]; @@ -108,6 +112,7 @@ public final class DefaultServiceConnection implements ServiceConnection { // 5. SET ALL GENERAL SERVICE CONNECTION INFORMATION: providerName = getProperty(tapConfig, KEY_PROVIDER_NAME); serviceDescription = getProperty(tapConfig, KEY_SERVICE_DESCRIPTION); + initMaxAsyncJobs(tapConfig); initRetentionPeriod(tapConfig); initExecutionDuration(tapConfig); @@ -230,6 +235,18 @@ public final class DefaultServiceConnection implements ServiceConnection { return metadata; } + private void initMaxAsyncJobs(final Properties tapConfig){ + // Get the property value: + String propValue = getProperty(tapConfig, KEY_MAX_ASYNC_JOBS); + try{ + // If a value is provided, cast it into an integer and set the attribute: + maxAsyncJobs = (propValue == null) ? DEFAULT_MAX_ASYNC_JOBS : Integer.parseInt(propValue); + }catch(NumberFormatException nfe){ + // If the value given in the Property file is not an integer, set the default value: + maxAsyncJobs = DEFAULT_MAX_ASYNC_JOBS; + } + } + private void initRetentionPeriod(final Properties tapConfig){ retentionPeriod = new int[2]; @@ -605,6 +622,11 @@ public final class DefaultServiceConnection implements ServiceConnection { return true; } + @Override + public int getNbMaxAsyncJobs(){ + return maxAsyncJobs; + } + @Override public UserIdentifier getUserIdentifier(){ return null; // NO USER IDENTIFICATION @@ -625,9 +647,4 @@ public final class DefaultServiceConnection implements ServiceConnection { return udfs; // FORBID ANY UNKNOWN FUNCTION } - @Override - public int getNbMaxAsyncJobs(){ - return -1; // UNLIMITED - } - } diff --git a/src/tap/config/TAPConfiguration.java b/src/tap/config/TAPConfiguration.java index 96f42fb..c6522b2 100644 --- a/src/tap/config/TAPConfiguration.java +++ b/src/tap/config/TAPConfiguration.java @@ -32,6 +32,10 @@ public final class TAPConfiguration { public final static String KEY_BACKUP_BY_USER = "backup_by_user"; public final static boolean DEFAULT_BACKUP_BY_USER = false; + /* ASYNCHRONOUS JOBS */ + public final static String KEY_MAX_ASYNC_JOBS = "max_async_jobs"; + public final static int DEFAULT_MAX_ASYNC_JOBS = 0; + /* EXECUTION DURATION */ public final static String KEY_DEFAULT_EXECUTION_DURATION = "default_execution_duration"; public final static String KEY_MAX_EXECUTION_DURATION = "max_execution_duration"; diff --git a/src/tap/config/tap_configuration_file.html b/src/tap/config/tap_configuration_file.html index c49cb18..84fed73 100644 --- a/src/tap/config/tap_configuration_file.html +++ b/src/tap/config/tap_configuration_file.html @@ -300,6 +300,19 @@ <td><ul><li>whole <em>(default)</em></li><li>user</li></ul></td> </tr> + <tr><td colspan="5">Asynchronous jobs management</td></tr> + <tr> + <td class="done">max_async_jobs</td> + <td></td> + <td>integer</td> + <td> + <p>Maximum number of asynchronous jobs that can run simultaneously.</p> + <p>A negative or null value means there is no restriction over the number of running asynchronous jobs.</p> + <p><em>By default, there is no restriction: max_async_jobs=0.</em></p> + </td> + <td><ul><li>0 <em>(default)</em></li><li>10</li></ul></td> + </tr> + <tr><td colspan="5">Query Execution</td></tr> <tr> <td class="done">default_execution_duration</td> diff --git a/src/tap/config/tap_full.properties b/src/tap/config/tap_full.properties index 886c6a2..b4b147b 100644 --- a/src/tap/config/tap_full.properties +++ b/src/tap/config/tap_full.properties @@ -124,36 +124,6 @@ default_retention_period = 0 # Default value: 0 (results kept forever). max_retention_period = 0 -# [OPTIONAL] -# Mandatory if file_manager=irods -# Host of the IRODS service. -#irods_host = - -# [OPTIONAL] -# Mandatory if file_manager=irods -# Port of the IRODS service located on the irodsHost host. -#irods_port = - -# [OPTIONAL] -# Mandatory if file_manager=irods -# Username to use in order to access the IRODS service located at irodsHost host. -#irods_user = - -# [OPTIONAL] -# Mandatory if file_manager=irods -# Password associated with the username used to access the IRODS service located at irodsHost host. -#irods_password = - -# [OPTIONAL] -# Mandatory if file_manager=irods -# Zone of the IRODS service in which the TAP Service must manage its files. -#irods_zone = - -# [OPTIONAL] -# Mandatory if file_manager=irods -# Default storage resource of the IRODS service. -#irods_default_storage_resource = - ############## # UWS_BACKUP # ############## @@ -168,6 +138,16 @@ backup_frequency = never # Allowed values are: user (one backup file for each user ; default), whole (one file for all users ; may generates a big file). backup_mode = user +##################### +# ASYNCHRONOUS JOBS # +##################### + +# [OPTIONAL] +# Maximum number of asynchronous jobs that can run simultaneously. +# A negative or null value means there is no restriction over the number of running asynchronous jobs. +# By default, there is no restriction: max_async_jobs=0. +max_async_jobs = 0 + ################### # QUERY_EXECUTION # ################### diff --git a/test/tap/config/TestDefaultServiceConnection.java b/test/tap/config/TestDefaultServiceConnection.java index fc0cd96..e45239d 100644 --- a/test/tap/config/TestDefaultServiceConnection.java +++ b/test/tap/config/TestDefaultServiceConnection.java @@ -4,8 +4,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static tap.config.TAPConfiguration.DEFAULT_MAX_ASYNC_JOBS; import static tap.config.TAPConfiguration.KEY_DEFAULT_OUTPUT_LIMIT; import static tap.config.TAPConfiguration.KEY_FILE_MANAGER; +import static tap.config.TAPConfiguration.KEY_MAX_ASYNC_JOBS; import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT; import static tap.config.TAPConfiguration.KEY_METADATA; import static tap.config.TAPConfiguration.KEY_METADATA_FILE; @@ -38,7 +40,8 @@ public class TestDefaultServiceConnection { private Properties validProp, noFmProp, fmClassPathProp, incorrectFmProp, xmlMetaProp, missingMetaProp, missingMetaFileProp, wrongMetaProp, wrongMetaFileProp, validFormatsProp, badSVFormat1Prop, - badSVFormat2Prop, unknownFormatProp, defaultOutputLimitProp, + badSVFormat2Prop, unknownFormatProp, maxAsyncProp, + negativeMaxAsyncProp, notIntMaxAsyncProp, defaultOutputLimitProp, maxOutputLimitProp, bothOutputLimitGoodProp, bothOutputLimitBadProp; @@ -86,6 +89,15 @@ public class TestDefaultServiceConnection { unknownFormatProp = (Properties)validProp.clone(); unknownFormatProp.setProperty(KEY_OUTPUT_FORMATS, "foo"); + maxAsyncProp = (Properties)validProp.clone(); + maxAsyncProp.setProperty(KEY_MAX_ASYNC_JOBS, "10"); + + negativeMaxAsyncProp = (Properties)validProp.clone(); + negativeMaxAsyncProp.setProperty(KEY_MAX_ASYNC_JOBS, "-2"); + + notIntMaxAsyncProp = (Properties)validProp.clone(); + notIntMaxAsyncProp.setProperty(KEY_MAX_ASYNC_JOBS, "foo"); + defaultOutputLimitProp = (Properties)validProp.clone(); defaultOutputLimitProp.setProperty(KEY_DEFAULT_OUTPUT_LIMIT, "100"); @@ -136,6 +148,7 @@ public class TestDefaultServiceConnection { assertTrue(connection.getTAPMetadata().getNbSchemas() >= 1); assertTrue(connection.getTAPMetadata().getNbTables() >= 5); assertTrue(connection.isAvailable()); + assertEquals(DEFAULT_MAX_ASYNC_JOBS, connection.getNbMaxAsyncJobs()); assertTrue(connection.getRetentionPeriod()[0] <= connection.getRetentionPeriod()[1]); assertTrue(connection.getExecutionDuration()[0] <= connection.getExecutionDuration()[1]); @@ -162,6 +175,7 @@ public class TestDefaultServiceConnection { assertEquals(nbSchemas, connection.getTAPMetadata().getNbSchemas()); assertEquals(nbTables, connection.getTAPMetadata().getNbTables()); assertTrue(connection.isAvailable()); + assertEquals(DEFAULT_MAX_ASYNC_JOBS, connection.getNbMaxAsyncJobs()); assertTrue(connection.getRetentionPeriod()[0] <= connection.getRetentionPeriod()[1]); assertTrue(connection.getExecutionDuration()[0] <= connection.getExecutionDuration()[1]); }catch(Exception e){ @@ -286,6 +300,30 @@ public class TestDefaultServiceConnection { assertEquals(e.getMessage(), "Unknown output format: foo"); } + // Valid value for max_async_jobs: + try{ + ServiceConnection connection = new DefaultServiceConnection(maxAsyncProp); + assertEquals(10, connection.getNbMaxAsyncJobs()); + }catch(Exception e){ + fail("This MUST have succeeded because a valid max_async_jobs is provided! \nCaught exception: " + getPertinentMessage(e)); + } + + // Negative value for max_async_jobs: + try{ + ServiceConnection connection = new DefaultServiceConnection(negativeMaxAsyncProp); + assertEquals(-2, connection.getNbMaxAsyncJobs()); + }catch(Exception e){ + fail("This MUST have succeeded because a negative max_async_jobs is equivalent to 'no restriction'! \nCaught exception: " + getPertinentMessage(e)); + } + + // A not integer value for max_async_jobs: + try{ + ServiceConnection connection = new DefaultServiceConnection(notIntMaxAsyncProp); + assertEquals(DEFAULT_MAX_ASYNC_JOBS, connection.getNbMaxAsyncJobs()); + }catch(Exception e){ + fail("This MUST have succeeded because a not integer value for max_async_jobs is considered as 'no restriction'! \nCaught exception: " + getPertinentMessage(e)); + } + // Test with no output limit specified: try{ ServiceConnection connection = new DefaultServiceConnection(validProp); -- GitLab