Commit d2e5d98a authored by gmantele's avatar gmantele
Browse files

[UWS] Support the blocking behavior described in PR-UWS-1.1.

It is possible to choose how the blocking mechanism should behave
(e.g. what the max. waiting period, how many requests can be blocked
in the same time, what happen when the blocking times out, ...).

Indeed, the policy to apply must actually be an extension of the interface
BlockingPolicy. Already two implementations are provided in the library
(LimitedBlockingPolicy and UserLimitedBlockingPolicy), but a custom policy
can perfectly be created and apply to a UWS service.

By default, no policy is set. In such case, the service will block the time
specified by the user, which may be -1 (i.e. wait indefinitely). A
BlockingPolicy can help controlling the waiting/blocking process and protect
the resources of the server.
parent f08018cb
Loading
Loading
Loading
Loading
+172 −119
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import uws.service.log.DefaultUWSLog;
import uws.service.log.UWSLog;
import uws.service.log.UWSLog.LogLevel;
import uws.service.request.RequestParser;
import uws.service.wait.BlockingPolicy;

/**
 * <p>This class implements directly the interface {@link UWS} and so, it represents the core of a UWS service.</p>
@@ -138,7 +139,7 @@ import uws.service.request.RequestParser;
 * </p>
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 4.2 (09/2017)
 * @version 4.3 (11/2017)
 */
public class UWSService implements UWS {

@@ -201,6 +202,16 @@ public class UWSService implements UWS {
	/** Lets writing/formatting any exception/throwable in a HttpServletResponse. */
	protected ServiceErrorWriter errorWriter;

	/**
	 * Strategy to use for the blocking/wait process concerning the
	 * {@link JobSummary} action.
	 * <p>
	 * 	If NULL, the standard strategy will be used: wait exactly the time asked
	 * 	by the user (or indefinitely if none is specified).
	 * </p>
	 * @since 4.3 */
	protected BlockingPolicy waitPolicy = null;

	/** Last generated request ID. If the next generated request ID is equivalent to this one,
	 * a new one will generate in order to ensure the unicity.
	 * @since 4.1 */
@@ -542,6 +553,48 @@ public class UWSService implements UWS {
		return requestParser;
	}

	/**
	 * Get the currently used strategy for the blocking behavior of the
	 * Job Summary action.
	 *
	 * <p>
	 * 	This strategy lets decide how long a WAIT request must block a HTTP
	 * 	request. With a such policy, the waiting time specified by the user may
	 * 	be modified.
	 * </p>
	 *
	 * @return	The WAIT strategy,
	 *        	or NULL if the default one (i.e. wait the time specified by the
	 *        	user) is used.
	 *
	 * @since 4.3
	 */
	public final BlockingPolicy getWaitPolicy(){
		return waitPolicy;
	}

	/**
	 * Set the strategy to use for the blocking behavior of the
	 * Job Summary action.
	 *
	 * <p>
	 * 	This strategy lets decide whether a WAIT request must block a HTTP
	 * 	request and how long. With a such policy, the waiting time specified by
	 * 	the user may be modified.
	 * </p>
	 *
	 * @param waitPolicy	The WAIT strategy to use,
	 *                  	or NULL if the default one (i.e. wait the time
	 *                  	specified by the user ;
	 *                  	if no time is specified the HTTP request may be
	 *                  	blocked indefinitely) must be used.
	 *
	 * @since 4.3
	 */
	public final void setWaitPolicy(final BlockingPolicy waitPolicy){
		this.waitPolicy = waitPolicy;
	}

	/* ******************** */
	/* HOME PAGE MANAGEMENT */
	/* ******************** */
+63 −1
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import uws.job.serializer.UWSSerializer;
import uws.job.serializer.XMLSerializer;
import uws.job.serializer.filter.JobListRefiner;
import uws.job.user.JobOwner;
import uws.service.actions.JobSummary;
import uws.service.actions.UWSAction;
import uws.service.backup.UWSBackupManager;
import uws.service.error.DefaultUWSErrorWriter;
@@ -71,6 +72,7 @@ import uws.service.log.UWSLog.LogLevel;
import uws.service.request.RequestParser;
import uws.service.request.UWSRequestParser;
import uws.service.request.UploadFile;
import uws.service.wait.BlockingPolicy;

/**
 * <p>
@@ -151,7 +153,7 @@ import uws.service.request.UploadFile;
 * </p>
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 4.3 (10/2017)
 * @version 4.3 (11/2017)
 */
public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory {
	private static final long serialVersionUID = 1L;
@@ -199,6 +201,17 @@ public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory
	/** Lets writing/formatting any exception/throwable in a HttpServletResponse. */
	protected ServiceErrorWriter errorWriter;

	/**
	 * Strategy to use for the blocking/wait process concerning the
	 * {@link #doJobSummary(UWSUrl, HttpServletRequest, HttpServletResponse, JobOwner)}
	 * action.
	 * <p>
	 * 	If NULL, the standard strategy will be used: wait exactly the time asked
	 * 	by the user (or indefinitely if none is specified).
	 * </p>
	 * @since 4.3 */
	protected BlockingPolicy waitPolicy = null;

	@Override
	public final void init(ServletConfig config) throws ServletException{
		super.init(config);
@@ -503,6 +516,52 @@ public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory
		}
	}

	/* ***************** */
	/* BLOCKING BEHAVIOR */
	/* ***************** */

	/**
	 * Get the currently used strategy for the blocking behavior of the
	 * Job Summary action.
	 *
	 * <p>
	 * 	This strategy lets decide how long a WAIT request must block a HTTP
	 * 	request. With a such policy, the waiting time specified by the user may
	 * 	be modified.
	 * </p>
	 *
	 * @return	The WAIT strategy,
	 *        	or NULL if the default one (i.e. wait the time specified by the
	 *        	user) is used.
	 *
	 * @since 4.3
	 */
	public final BlockingPolicy getWaitPolicy(){
		return waitPolicy;
	}

	/**
	 * Set the strategy to use for the blocking behavior of the
	 * Job Summary action.
	 *
	 * <p>
	 * 	This strategy lets decide whether a WAIT request must block a HTTP
	 * 	request and how long. With a such policy, the waiting time specified by
	 * 	the user may be modified.
	 * </p>
	 *
	 * @param waitPolicy	The WAIT strategy to use,
	 *                  	or NULL if the default one (i.e. wait the time
	 *                  	specified by the user ;
	 *                  	if no time is specified the HTTP request may be
	 *                  	blocked indefinitely) must be used.
	 *
	 * @since 4.3
	 */
	public final void setWaitPolicy(final BlockingPolicy waitPolicy){
		this.waitPolicy = waitPolicy;
	}

	/* *********** */
	/* UWS ACTIONS */
	/* *********** */
@@ -604,6 +663,9 @@ public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory
		// Get the job:
		UWSJob job = getJob(requestUrl);

		// Block if necessary:
		JobSummary.block(waitPolicy, req, job, user);

		// Write the job summary:
		UWSSerializer serializer = getSerializer(req.getHeader("Accept"));
		resp.setContentType(serializer.getMimeType());
+208 −19
Original line number Diff line number Diff line
@@ -16,11 +16,12 @@ package uws.service.actions;
 * You should have received a copy of the GNU Lesser General Public License
 * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2012-2015 - 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)
 */

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
@@ -28,27 +29,40 @@ import javax.servlet.http.HttpServletResponse;

import uws.UWSException;
import uws.UWSToolBox;
import uws.job.ExecutionPhase;
import uws.job.UWSJob;
import uws.job.serializer.UWSSerializer;
import uws.job.user.JobOwner;
import uws.service.UWSService;
import uws.service.UWSUrl;
import uws.service.log.UWSLog.LogLevel;
import uws.service.wait.BlockingPolicy;
import uws.service.wait.WaitObserver;

/**
 * <p>The "Get Job" action of a UWS.</p>
 * The "Get Job" action of a UWS.
 *
 * <p><i><u>Note:</u> The corresponding name is {@link UWSAction#JOB_SUMMARY}.</i></p>
 * <p><i>Note:
 * 	The corresponding name is {@link UWSAction#JOB_SUMMARY}.
 * </i></p>
 *
 * <p>This action returns the summary of the job specified in the given UWS URL.
 * This summary is serialized by the {@link UWSSerializer} choosed in function of the HTTP Accept header.</p>
 * <p>
 * 	This action returns the summary of the job specified in the given UWS URL.
 * 	This summary is serialized by the {@link UWSSerializer} chosen in function
 * 	of the HTTP Accept header.
 * </p>
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 4.1 (04/2015)
 * @version 4.3 (11/2017)
 */
public class JobSummary extends UWSAction {
	private static final long serialVersionUID = 1L;

	/** Name of the parameter which allows the blocking behavior
	 * (for a specified or unlimited duration) of a {@link JobSummary} request.
	 * @since 4.3 */
	public final static String WAIT_PARAMETER = "WAIT";

	public JobSummary(UWSService u){
		super(u);
	}
@@ -70,8 +84,11 @@ public class JobSummary extends UWSAction {
	/**
	 * Checks whether:
	 * <ul>
	 * 	<li>a job list name is specified in the given UWS URL <i>(<u>note:</u> the existence of the jobs list is not checked)</i>,</li>
	 * 	<li>a job ID is given in the UWS URL <i>(<u>note:</u> the existence of the job is not checked)</i>,</li>
	 * 	<li>a job list name is specified in the given UWS URL
	 * 		<i>(<u>note:</u> the existence of the jobs list is not checked)</i>,
	 * 	</li>
	 * 	<li>a job ID is given in the UWS URL
	 * 		<i>(<u>note:</u> the existence of the job is not checked)</i>,</li>
	 * 	<li>there is no job attribute,</li>
	 * 	<li>the HTTP method is HTTP-GET.</li>
	 * </ul>
@@ -85,7 +102,8 @@ public class JobSummary extends UWSAction {

	/**
	 * Gets the specified job <i>(and throw an error if not found)</i>,
	 * chooses the serializer and write the serialization of the job in the given response.
	 * chooses the serializer and write the serialization of the job in the
	 * given response.
	 *
	 * @see #getJob(UWSUrl)
	 * @see UWSService#getSerializer(String)
@@ -98,6 +116,9 @@ public class JobSummary extends UWSAction {
		// Get the job:
		UWSJob job = getJob(urlInterpreter);

		// Block if necessary:
		JobSummary.block(uws.getWaitPolicy(), request, job, user);

		// Write the job summary:
		UWSSerializer serializer = uws.getSerializer(request.getHeader("Accept"));
		response.setContentType(serializer.getMimeType());
@@ -115,4 +136,172 @@ public class JobSummary extends UWSAction {
		return true;
	}

	/**
	 * Block the current thread until the specified duration (in seconds) is
	 * elapsed or if the execution phase of the target job changes.
	 *
	 * <p>
	 * 	A blocking is performed only if the given job is in an active phase
	 * 	(i.e. PENDING, QUEUED or EXECUTING).
	 * </p>
	 *
	 * <p>This function expects the 2 following HTTP-GET parameters:</p>
	 * <ul>
	 * 	<li><b>WAIT</b>: <i>[MANDATORY]</i> with a value (in seconds). The value
	 * 		             must be a positive and not null integer expressing a
	 * 		             duration in seconds or -1 (or any other negative value)
	 * 		             for an infinite time. If a not legal value or no value
	 * 		             is provided, the parameter will be merely ignored.
	 * 		             <br/>
	 * 	                 This parameter raises a flag meaning a blocking is
	 * 		             required (except if 0 is provided) and eventually a
	 * 		             time (in seconds) to wait before stop blocking.
	 * 		             <br/>
	 * 	                 If several values are provided, only the one meaning
	 * 		             the smallest blocking waiting time will be kept.
	 * 		             Particularly if both a negative and a positive or null
	 * 		             value are given, only the positive or null value will
	 * 		             be kept.</li>
	 *
	 * 	<li><b>PHASE</b>: <i>[OPTIONAL]</i> A legal execution phase must be
	 * 		              provided, otherwise this parameter will be ignored.
	 * 		              <br/>
	 * 	                  This parameter indicates the phase in which the job
	 * 		              must be at the time the blocking is required. If the
	 * 		              current job phase is different from the specified one,
	 * 		              no blocking will be performed. Note that the allowed
	 * 		              phases are PENDING, QUEUED and EXECUTING, because only
	 * 		              a job in one of these phases can be blocked.
	 * 		              <br/>
	 * 	                  If several values are provided, only the last
	 * 		              occurrence is kept.</li>
	 * </ul>
	 *
	 * <p><i>Note:
	 * 	A waiting time of 0 will be interpreted as "no blocking".
	 * </i></p>
	 *
	 * <p><i>Note:
	 * 	This function will have no effect if the given thread, the given HTTP
	 * 	request or the given job is NULL.
	 * </i></p>
	 *
	 * @param policy		Strategy to adopt for the blocking behavior.
	 *              		<i>If NULL, the standard blocking behavior will be
	 *              		performed: block the duration (eventually unlimited)
	 *              		specified by the user.</i>
	 * @param req			The HTTP request which asked for the blocking.
	 *           			<b>MUST NOT be NULL, otherwise no blocking will be
	 *           			performed.</b>
	 * @param job			The job associate with the HTTP request.
	 *           			<b>MUST NOT be NULL, otherwise no blocking will be
	 *           			performed.</b>
	 * @param user			The user who asked for the blocking behavior.
	 *            			<i>NULL if no user is logged in.</i>
	 *
	 * @since 4.3
	 */
	public static void block(final BlockingPolicy policy, final HttpServletRequest req, final UWSJob job, final JobOwner user){
		if (req == null || job == null)
			return;

		/* No blocking if the job is not in an "active" phase: */
		if (job.getPhase() != ExecutionPhase.PENDING && job.getPhase() != ExecutionPhase.QUEUED && job.getPhase() != ExecutionPhase.EXECUTING)
			return;

		/* Extract the parameters WAIT (only the smallest waiting time is taken
		 * into account) and PHASE (only the last legal occurrence is taken into
		 * account): */
		ExecutionPhase phase = null;
		boolean waitGiven = false;
		long waitingTime = 0;
		String param;
		String[] values;
		Enumeration<String> parameters = req.getParameterNames();
		while(parameters.hasMoreElements()){
			param = parameters.nextElement();
			values = req.getParameterValues(param);
			// CASE: WAIT parameter
			if (param.toUpperCase().equals("WAIT")){
				/* note: a value MUST be given for a WAIT parameter ; if it is
				 *       missing the parameter is ignored */
				if (values != null){
					for(int i = 0; i < values.length; i++){
						try{
							if (values[i] != null && values[i].trim().length() > 0){
								long tmp = Long.parseLong(values[i]);
								if (tmp < 0 && !waitGiven)
									waitingTime = tmp;
								else if (tmp >= 0)
									waitingTime = (waitGiven && waitingTime >= 0) ? Math.min(waitingTime, tmp) : tmp;
								waitGiven = true;
							}
						}catch(NumberFormatException nfe){}
					}
				}
			}
			// CASE: PHASE parameter
			else if (param.toUpperCase().equals("PHASE") && values != null){
				for(int i = values.length - 1; phase == null && i >= 0; i--){
					try{
						if (values[i].trim().length() > 0)
							phase = ExecutionPhase.valueOf(values[i].toUpperCase());
					}catch(IllegalArgumentException iae){}
				}
			}
		}

		/* The HTTP-GET request should block until either the specified time
		 * (or the timeout) is reached or if the job phase changed: */
		if (waitingTime != 0 && (phase == null || job.getPhase() == phase)){
			Thread threadToBlock = Thread.currentThread();
			WaitObserver observer = null;

			/* Eventually limit the waiting time in function of the chosen
			 * policy: */
			if (policy != null)
				waitingTime = policy.block(threadToBlock, waitingTime, job, user, req);

			/* Blocking ONLY IF the duration is NOT NULL (i.e. wait during 0
			 * seconds): */
			if (waitingTime != 0){
				try{
					/* Watch the job in order to detect an execution phase
					 * modification: */
					observer = new WaitObserver(threadToBlock);
					job.addObserver(observer);

					/* If the job is still processing, then wait the specified
					 * time: */
					if (job.getPhase() == ExecutionPhase.PENDING || job.getPhase() == ExecutionPhase.QUEUED || job.getPhase() == ExecutionPhase.EXECUTING){
						synchronized(threadToBlock){
							// Limited duration:
							if (waitingTime > 0)
								threadToBlock.wait(waitingTime * 1000);
							/* "Unlimited" duration (the wait will stop only if
							 * the job phase changes): */
							else
								threadToBlock.wait();
						}
					}

				}catch(InterruptedException ie){
					/* If the WAIT has been interrupted, the blocking
					 * is stopped and nothing special should happen. */
				}
				/* Clear all retained resources. */
				finally{
					// Do not observe any more the job:
					if (observer != null)
						job.removeObserver(observer);

					/* Notify the BlockingPolicy that this Thread is no longer
					 * blocked: */
					if (policy != null)
						policy.unblocked(threadToBlock, job, user, req);
				}
			}
		}
	}

}
+114 −0
Original line number Diff line number Diff line
package uws.service.wait;

/*
 * This file is part of UWSLibrary.
 *
 * UWSLibrary 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.
 *
 * UWSLibrary 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 UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2017 - Astronomisches Rechen Institut (ARI)
 */

import javax.servlet.http.HttpServletRequest;

import uws.job.UWSJob;
import uws.job.user.JobOwner;

/**
 * Implementations of this interface define the policy to apply when a blocking
 * of a request is asked by a UWS client.
 *
 * @author Gr&eacute;gory Mantelet (ARI)
 * @version 4.3 (11/2017)
 * @since 4.3
 */
public interface BlockingPolicy {

	/**
	 * Notify this {@link BlockingPolicy} that the given thread is going to
	 * be blocked for the specified duration. This function then decides how
	 * long the given thread must really wait before resuming.
	 *
	 * <p>
	 * 	The parameter "userDuration" and the returned value are durations
	 * 	expressed in seconds. Both follow the same rules:
	 * </p>
	 * <ul>
	 * 	<li><u>If &lt; 0</u>, the request will wait theoretically
	 * 		                  indefinitely.</li>
	 * 	<li><u>If 0</u>, the request will return immediately ; no wait.</li>
	 * 	<li><u>If &gt; 0</u>, the request will wait for the specified amount of
	 * 		                  seconds.</li>
	 * </ul>
	 *
	 * <p>
	 * 	Since a timeout or another special behavior may be chosen by this
	 * 	{@link BlockingPolicy}, the returned value may be different from the
	 * 	user's asked duration. The value that should be taken into account is
	 * 	obviously the returned one.
	 * </p>
	 *
	 * <p><i><b>IMPORTANT:</b>
	 * 	This function may <b>UN</b>block an older request/thread, in function of
	 * 	the strategy chosen/implemented by this {@link BlockingPolicy}.
	 * </i></p>
	 *
	 * @param thread		Thread that is going to be blocked.
	 *                      <i>MUST NOT be NULL. If NULL this function will
	 *                      either do nothing and return 0 (no blocking)
	 *                      or throw a {@link NullPointerException}.</i>
	 * @param userDuration	Waiting duration (in seconds) asked by the user.
	 *                    	<i>&lt; 0 means indefinite, 0 means no wait and
	 *                    	&gt; 0 means waiting for the specified amount of
	 *                    	seconds.</i>
	 * @param job			The job associated with the thread.
	 *           			<i>Should not be NULL.</i>
	 * @param user			The user who asked for the blocking behavior.
	 *            			<i>If NULL, the request will be concerned as
	 *            			anonymous and a decision to identify the user
	 *            			(e.g. use the IP address) may be chosen by the
	 *            			{@link BlockingPolicy} implementation if
	 *            			required.</i>
	 * @param request		The request which is going to be blocked.
	 *               		<i>Should not be NULL.</i>
	 *
	 * @return	The real duration (in seconds) that the UWS service must wait
	 *        	before returning a response to the given HTTP request.
	 *        	<i>&lt; 0 means indefinite, 0 means no wait and &gt; 0 means
	 *        	waiting for the specified amount of seconds.</i>
	 *
	 * @throws NullPointerException	If the given thread is NULL.
	 */
	public long block(final Thread thread, final long userDuration, final UWSJob job, final JobOwner user, final HttpServletRequest request) throws NullPointerException;

	/**
	 * Notify this {@link BlockingPolicy} that the given thread is not blocked
	 * anymore.
	 *
	 * @param unblockedThread	Thread that is not blocked any more.
	 *                       	<b>MUST be NOT NULL.</b>
	 * @param job				The job associated with the unblocked Thread.
	 *           				<i>Should not be NULL.</i>
	 * @param user				The user who originally asked for the blocking
	 *            				behavior.
	 *            				<i>If NULL, the request will be concerned as
	 *            				anonymous and a decision to identify the user
	 *            				(e.g. use the IP address) may be chosen by the
	 *            				{@link BlockingPolicy} implementation if
	 *            				required.</i>
	 * @param request			The request which has been unblocked.
	 *               			<i>Should not be NULL.</i>
	 */
	public void unblocked(final Thread unblockedThread, final UWSJob job, final JobOwner user, final HttpServletRequest request);

}
 No newline at end of file
+89 −0
Original line number Diff line number Diff line
package uws.service.wait;

/*
 * This file is part of UWSLibrary.
 *
 * UWSLibrary 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.
 *
 * UWSLibrary 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 UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2017 - Astronomisches Rechen Institut (ARI)
 */

import javax.servlet.http.HttpServletRequest;

import uws.job.UWSJob;
import uws.job.user.JobOwner;

/**
 * In this {@link BlockingPolicy}, the blocking is limited by a maximum
 * waiting time. Thus, unlimited blocking is prevented.
 *
 * <p>
 * 	More concretely, if no timeout is specified by the user, {@link #timeout} is
 * 	returned.
 * </p>
 *
 * <p>
 * 	If at creation of this policy no timeout is specified, a default one is set:
 * 	{@link #DEFAULT_TIMEOUT} (= {@value #DEFAULT_TIMEOUT} seconds).
 * </p>
 *
 * @author Gr&eacute;gory Mantelet (ARI)
 * @version 4.3 (11/2017)
 * @since 4.3
 */
public class LimitedBlockingPolicy implements BlockingPolicy {

	/** Default timeout (in seconds) set by this policy at creation if none is
	 * specified. */
	public final static long DEFAULT_TIMEOUT = 60;

	/** Maximum blocking duration (in seconds).
	 * <i>This attribute is set by default to {@link #DEFAULT_TIMEOUT}. */
	protected long timeout = DEFAULT_TIMEOUT;

	/**
	 * Build a blocking policy with the default timeout
	 * (= {@value #DEFAULT_TIMEOUT} seconds).
	 */
	public LimitedBlockingPolicy(){}

	/**
	 * Build a {@link BlockingPolicy} which will limit blocking duration to the
	 * given value.
	 *
	 * <p><i>IMPORTANT:
	 * 	If {@link #timeout} is &lt; 0, the default timeout
	 * 	(i.e. {@value #DEFAULT_TIMEOUT}) will be set automatically by this
	 * 	constructor.
	 * </i></p>
	 *
	 * @param timeout	Maximum blocking duration (in seconds).
	 */
	public LimitedBlockingPolicy(final long timeout){
		this.timeout = (timeout < 0) ? DEFAULT_TIMEOUT : timeout;
	}

	@Override
	public long block(final Thread thread, final long userDuration, final UWSJob job, final JobOwner user, final HttpServletRequest request){
		// Nothing should happen if no thread and/or no job is provided:
		if (job == null || thread == null)
			return 0;

		return (userDuration < 0 || userDuration > timeout) ? timeout : userDuration;
	}

	@Override
	public void unblocked(final Thread unblockedThread, final UWSJob job, final JobOwner user, final HttpServletRequest request){}

}
 No newline at end of file
Loading