ARTEMIS-1462 Allow ActiveMQScheduledComponent initial delay configuration
It contains: - an improved documentation of the constructors - the initial delay configuration
This commit is contained in:
parent
b09ea433b5
commit
40f49ef0bc
|
@ -37,6 +37,7 @@ public abstract class ActiveMQScheduledComponent implements ActiveMQComponent, R
|
|||
private static final Logger logger = Logger.getLogger(ActiveMQScheduledComponent.class);
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
private boolean startedOwnScheduler;
|
||||
private long initialDelay;
|
||||
private long period;
|
||||
private long millisecondsPeriod;
|
||||
private TimeUnit timeUnit;
|
||||
|
@ -48,27 +49,79 @@ public abstract class ActiveMQScheduledComponent implements ActiveMQComponent, R
|
|||
|
||||
private final AtomicInteger delayed = new AtomicInteger(0);
|
||||
|
||||
/**
|
||||
* It creates a scheduled component that can trigger {@link #run()} with a fixed {@code checkPeriod} on a configured {@code executor}.
|
||||
*
|
||||
* @param scheduledExecutorService the {@link ScheduledExecutorService} that periodically trigger {@link #run()} on the configured {@code executor}
|
||||
* @param executor the {@link Executor} that execute {@link #run()} when triggered
|
||||
* @param initialDelay the time to delay first execution
|
||||
* @param checkPeriod the delay between the termination of one execution and the start of the next
|
||||
* @param timeUnit the time unit of the {@code initialDelay} and {@code checkPeriod} parameters
|
||||
* @param onDemand if {@code true} the task won't be scheduled on {@link #start()}, {@code false} otherwise
|
||||
*/
|
||||
public ActiveMQScheduledComponent(ScheduledExecutorService scheduledExecutorService,
|
||||
Executor executor,
|
||||
long initialDelay,
|
||||
long checkPeriod,
|
||||
TimeUnit timeUnit,
|
||||
boolean onDemand) {
|
||||
this.executor = executor;
|
||||
this.scheduledExecutorService = scheduledExecutorService;
|
||||
this.initialDelay = initialDelay;
|
||||
this.period = checkPeriod;
|
||||
this.timeUnit = timeUnit;
|
||||
this.onDemand = onDemand;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is useful for cases where we want our own scheduler executor.
|
||||
* It creates a scheduled component that can trigger {@link #run()} with a fixed {@code checkPeriod} on a configured {@code executor}.
|
||||
*
|
||||
* @param checkPeriod
|
||||
* @param timeUnit
|
||||
* @param onDemand
|
||||
* <p>
|
||||
* The component created will have {@code initialDelay} defaulted to {@code checkPeriod}.
|
||||
*
|
||||
* @param scheduledExecutorService the {@link ScheduledExecutorService} that periodically trigger {@link #run()} on the configured {@code executor}
|
||||
* @param executor the {@link Executor} that execute {@link #run()} when triggered
|
||||
* @param checkPeriod the delay between the termination of one execution and the start of the next
|
||||
* @param timeUnit the time unit of the {@code initialDelay} and {@code checkPeriod} parameters
|
||||
* @param onDemand if {@code true} the task won't be scheduled on {@link #start()}, {@code false} otherwise
|
||||
*/
|
||||
public ActiveMQScheduledComponent(ScheduledExecutorService scheduledExecutorService,
|
||||
Executor executor,
|
||||
long checkPeriod,
|
||||
TimeUnit timeUnit,
|
||||
boolean onDemand) {
|
||||
this(scheduledExecutorService, executor, checkPeriod, checkPeriod, timeUnit, onDemand);
|
||||
}
|
||||
|
||||
/**
|
||||
* It creates a scheduled component that can trigger {@link #run()} with a fixed {@code checkPeriod} on a configured {@code executor}.
|
||||
*
|
||||
* <p>
|
||||
* This is useful for cases where we want our own scheduler executor: on {@link #start()} it will create a fresh new single-threaded {@link ScheduledExecutorService}
|
||||
* using {@link #getThreadFactory()} and {@link #getThisClassLoader()}, while on {@link #stop()} it will garbage it.
|
||||
*
|
||||
* @param initialDelay the time to delay first execution
|
||||
* @param checkPeriod the delay between the termination of one execution and the start of the next
|
||||
* @param timeUnit the time unit of the {@code initialDelay} and {@code checkPeriod} parameters
|
||||
* @param onDemand if {@code true} the task won't be scheduled on {@link #start()}, {@code false} otherwise
|
||||
*/
|
||||
public ActiveMQScheduledComponent(long initialDelay, long checkPeriod, TimeUnit timeUnit, boolean onDemand) {
|
||||
this(null, null, initialDelay, checkPeriod, timeUnit, onDemand);
|
||||
}
|
||||
|
||||
/**
|
||||
* It creates a scheduled component that can trigger {@link #run()} with a fixed {@code checkPeriod} on a configured {@code executor}.
|
||||
*
|
||||
* <p>
|
||||
* This is useful for cases where we want our own scheduler executor.
|
||||
* The component created will have {@code initialDelay} defaulted to {@code checkPeriod}.
|
||||
*
|
||||
* @param checkPeriod the delay between the termination of one execution and the start of the next
|
||||
* @param timeUnit the time unit of the {@code initialDelay} and {@code checkPeriod} parameters
|
||||
* @param onDemand if {@code true} the task won't be scheduled on {@link #start()}, {@code false} otherwise
|
||||
*/
|
||||
public ActiveMQScheduledComponent(long checkPeriod, TimeUnit timeUnit, boolean onDemand) {
|
||||
this(null, null, checkPeriod, timeUnit, onDemand);
|
||||
this(null, null, checkPeriod, checkPeriod, timeUnit, onDemand);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,7 +144,7 @@ public abstract class ActiveMQScheduledComponent implements ActiveMQComponent, R
|
|||
this.millisecondsPeriod = timeUnit.convert(period, TimeUnit.MILLISECONDS);
|
||||
|
||||
if (period >= 0) {
|
||||
future = scheduledExecutorService.scheduleWithFixedDelay(runForScheduler, period, period, timeUnit);
|
||||
future = scheduledExecutorService.scheduleWithFixedDelay(runForScheduler, initialDelay, period, timeUnit);
|
||||
} else {
|
||||
logger.tracef("did not start scheduled executor on %s because period was configured as %d", this, period);
|
||||
}
|
||||
|
@ -133,6 +186,39 @@ public abstract class ActiveMQScheduledComponent implements ActiveMQComponent, R
|
|||
return this;
|
||||
}
|
||||
|
||||
public long getInitialDelay() {
|
||||
return initialDelay;
|
||||
}
|
||||
|
||||
public synchronized ActiveMQScheduledComponent setInitialDelay(long initialDelay) {
|
||||
this.initialDelay = initialDelay;
|
||||
restartIfNeeded();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful to change a running schedule and avoid multiple restarts.
|
||||
*/
|
||||
public synchronized ActiveMQScheduledComponent setInitialDelayAndPeriod(long initialDelay, long period) {
|
||||
this.period = period;
|
||||
this.initialDelay = initialDelay;
|
||||
restartIfNeeded();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful to change a running schedule and avoid multiple restarts.
|
||||
*/
|
||||
public synchronized ActiveMQScheduledComponent setInitialDelayAndPeriod(long initialDelay,
|
||||
long period,
|
||||
TimeUnit timeUnit) {
|
||||
this.period = period;
|
||||
this.initialDelay = initialDelay;
|
||||
this.timeUnit = timeUnit;
|
||||
restartIfNeeded();
|
||||
return this;
|
||||
}
|
||||
|
||||
public TimeUnit getTimeUnit() {
|
||||
return timeUnit;
|
||||
}
|
||||
|
|
|
@ -165,4 +165,37 @@ public class ActiveMQScheduledComponentTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsingCustomInitialDelay() throws InterruptedException {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final long initialDelayMillis = 100;
|
||||
final long checkPeriodMillis = 100 * initialDelayMillis;
|
||||
final ActiveMQScheduledComponent local = new ActiveMQScheduledComponent(scheduledExecutorService, executorService, initialDelayMillis, checkPeriodMillis, TimeUnit.MILLISECONDS, false) {
|
||||
@Override
|
||||
public void run() {
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
final long start = System.nanoTime();
|
||||
local.start();
|
||||
try {
|
||||
final boolean triggeredBeforePeriod = latch.await(local.getPeriod(), local.getTimeUnit());
|
||||
final long timeToFirstTrigger = TimeUnit.NANOSECONDS.convert(System.nanoTime() - start, local.getTimeUnit());
|
||||
Assert.assertTrue("Takes too long to start", triggeredBeforePeriod);
|
||||
Assert.assertTrue("Started too early", timeToFirstTrigger >= local.getInitialDelay());
|
||||
} finally {
|
||||
local.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifyDefaultInitialDelay() throws InterruptedException {
|
||||
final ActiveMQScheduledComponent local = new ActiveMQScheduledComponent(scheduledExecutorService, executorService, 100, TimeUnit.MILLISECONDS, false) {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
}
|
||||
};
|
||||
Assert.assertEquals("The initial delay must be defaulted to the period", local.getPeriod(), local.getInitialDelay());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue