|
|
|
@ -51,8 +51,8 @@ public abstract class ConcurrencyThrottleSupport implements Serializable { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Concurrency limit which signals unbounded concurrency: {@value}. |
|
|
|
* Concurrency limit which signals unbounded concurrency: {@value}. |
|
|
|
* <p>Setting the limit to this value permits any number of concurrent |
|
|
|
* <p>Setting the limit to this value permits any number of concurrent access: |
|
|
|
* invocations: that is, concurrency will not be throttled. |
|
|
|
* that is, concurrency will not be throttled. |
|
|
|
* @see #NO_CONCURRENCY |
|
|
|
* @see #NO_CONCURRENCY |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static final int UNBOUNDED_CONCURRENCY = -1; |
|
|
|
public static final int UNBOUNDED_CONCURRENCY = -1; |
|
|
|
@ -60,7 +60,7 @@ public abstract class ConcurrencyThrottleSupport implements Serializable { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Concurrency limit which signals that concurrency throttling has been |
|
|
|
* Concurrency limit which signals that concurrency throttling has been |
|
|
|
* disabled: {@value}. |
|
|
|
* disabled: {@value}. |
|
|
|
* <p>Setting the limit to this value prevents all invocations. |
|
|
|
* <p>Setting the limit to this value prevents all access. |
|
|
|
* @see #beforeAccess() |
|
|
|
* @see #beforeAccess() |
|
|
|
* @see #UNBOUNDED_CONCURRENCY |
|
|
|
* @see #UNBOUNDED_CONCURRENCY |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@ -117,8 +117,7 @@ public abstract class ConcurrencyThrottleSupport implements Serializable { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected void beforeAccess() { |
|
|
|
protected void beforeAccess() { |
|
|
|
if (this.concurrencyLimit == NO_CONCURRENCY) { |
|
|
|
if (this.concurrencyLimit == NO_CONCURRENCY) { |
|
|
|
throw new IllegalStateException( |
|
|
|
onAccessRejected("Concurrency limit set to NO_CONCURRENCY - not allowed to enter"); |
|
|
|
"Currently no invocations allowed - concurrency limit set to NO_CONCURRENCY"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (this.concurrencyLimit > 0) { |
|
|
|
if (this.concurrencyLimit > 0) { |
|
|
|
this.concurrencyLock.lock(); |
|
|
|
this.concurrencyLock.lock(); |
|
|
|
@ -146,7 +145,7 @@ public abstract class ConcurrencyThrottleSupport implements Serializable { |
|
|
|
boolean interrupted = false; |
|
|
|
boolean interrupted = false; |
|
|
|
while (this.concurrencyCount >= this.concurrencyLimit) { |
|
|
|
while (this.concurrencyCount >= this.concurrencyLimit) { |
|
|
|
if (interrupted) { |
|
|
|
if (interrupted) { |
|
|
|
throw new IllegalStateException("Thread was interrupted while waiting for invocation access, " + |
|
|
|
onAccessRejected("Thread was interrupted while waiting for access " + |
|
|
|
"but concurrency limit still does not allow for entering"); |
|
|
|
"but concurrency limit still does not allow for entering"); |
|
|
|
} |
|
|
|
} |
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
@ -164,6 +163,21 @@ public abstract class ConcurrencyThrottleSupport implements Serializable { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Triggered when access has been rejected due to the concurrency policy |
|
|
|
|
|
|
|
* or due to interruption. |
|
|
|
|
|
|
|
* <p>Implementations will typically throw a corresponding exception. |
|
|
|
|
|
|
|
* When returning normally, regular access will still be attempted. |
|
|
|
|
|
|
|
* <p>The default implementation throws an {@link IllegalStateException}. |
|
|
|
|
|
|
|
* @param msg the rejection message (common exception messages are designed |
|
|
|
|
|
|
|
* so that they can be appended with an identifier separated by a space |
|
|
|
|
|
|
|
* in custom subclasses) |
|
|
|
|
|
|
|
* @since 7.0.4 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
protected void onAccessRejected(String msg) { |
|
|
|
|
|
|
|
throw new IllegalStateException(msg); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* To be invoked after the main execution logic of concrete subclasses. |
|
|
|
* To be invoked after the main execution logic of concrete subclasses. |
|
|
|
* @see #beforeAccess() |
|
|
|
* @see #beforeAccess() |
|
|
|
|