use of org.eclipse.scout.rt.platform.util.concurrent.TimedOutError in project scout.rt by eclipse.
the class PeriodicJobMutexTest method testInternal.
/**
* This test schedules a job according to the given input.
* <p>
* After 2 iterations, the periodic job is cancelled. While running, this job is checked to be the mutex owner. Then,
* another job with the same mutex is scheduled and awaited for (timeout expected because mutual exclusion). And
* finally, another job with the same mutex is scheduled, which is expected to be run after the timed out job. Both
* that jobs are expected to be run right after one iterations completes.
*/
private void testInternal(final ScheduleBuilder<? extends Trigger> periodicScheduleBuilder, final IExecutionSemaphore executionSemaphore) {
// synchronized because modified/read by different threads.
final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
final AtomicInteger rounds = new AtomicInteger(0);
final BlockingCountDownLatch latch = new BlockingCountDownLatch(2);
// Schedule other job
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("other job");
latch.countDown();
}
}, Jobs.newInput().withExecutionSemaphore(executionSemaphore));
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
latch.await();
// cancel after 2 iterations
if (rounds.getAndIncrement() == 2) {
IFuture.CURRENT.get().cancel(false);
return;
}
protocol.add("begin");
// This task should be mutex-owner
IFuture<?> currentFuture = IFuture.CURRENT.get();
IExecutionSemaphore mutex = currentFuture.getExecutionSemaphore();
if (mutex != null && mutex.isPermitOwner(currentFuture)) {
protocol.add("mutex-owner");
}
// Schedule other job with same mutex, and wait for it to complete.
// expected: that job must not commence execution until the periodic job completes this iteration
// However, to circumvent deadlock-detection, schedule this job within another job, that is not mutex owner
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
try {
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("running-2");
}
}, Jobs.newInput().withExecutionSemaphore(executionSemaphore).withExecutionHint(JOB_IDENTIFIER)).awaitDone(200, TimeUnit.MILLISECONDS);
} catch (TimedOutError e) {
protocol.add("timeout-because-mutex-owner");
}
}
}, Jobs.newInput().withExecutionHint(JOB_IDENTIFIER)).awaitDone();
// Schedule other job with same mutex
// expected: must only commence execution once this iteration completes.
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("running-3");
}
}, Jobs.newInput().withExecutionSemaphore(executionSemaphore).withExecutionHint(JOB_IDENTIFIER));
protocol.add("end");
}
}, Jobs.newInput().withExecutionHint(JOB_IDENTIFIER).withExecutionSemaphore(executionSemaphore).withExecutionTrigger(Jobs.newExecutionTrigger().withStartIn(200, // execute with a delay
TimeUnit.MILLISECONDS).withSchedule(// periodic schedule plan
periodicScheduleBuilder)));
latch.countDown();
// Wait for the job to complete
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter(), 10, TimeUnit.SECONDS);
List<String> expected = new ArrayList<String>();
expected.add("other job");
expected.add("begin");
expected.add("mutex-owner");
expected.add("timeout-because-mutex-owner");
expected.add("end");
expected.add("running-2");
expected.add("running-3");
expected.add("begin");
expected.add("mutex-owner");
expected.add("timeout-because-mutex-owner");
expected.add("end");
expected.add("running-2");
expected.add("running-3");
assertEquals(expected, protocol);
}
use of org.eclipse.scout.rt.platform.util.concurrent.TimedOutError in project scout.rt by eclipse.
the class WhenDoneScheduleTest method testSemaphore.
@Test
@Times(20)
public void testSemaphore() throws InterruptedException {
final BlockingCountDownLatch setupLatch = new BlockingCountDownLatch(1);
IExecutionSemaphore mutex = Jobs.newExecutionSemaphore(1).seal();
// Schedule arbitrary job with same semaphore
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
setupLatch.countDownAndBlock();
}
}, Jobs.newInput().withExecutionSemaphore(mutex));
// Schedule future
IFuture<String> future = Jobs.schedule(new Callable<String>() {
@Override
public String call() throws Exception {
return "abc";
}
}, Jobs.newInput().withExceptionHandling(null, // to not work with JUnitExceptionHandler
true));
// Schedule function with same semaphore
final AtomicBoolean functionExecuted = new AtomicBoolean(false);
IFuture<Void> functionFuture = future.whenDoneSchedule(new IBiFunction<String, Throwable, Void>() {
@Override
public Void apply(String result, Throwable error) {
functionExecuted.set(true);
return null;
}
}, Jobs.newInput().withExecutionSemaphore(mutex));
assertEquals("abc", future.awaitDoneAndGet(5, TimeUnit.SECONDS));
JobTestUtil.waitForPermitCompetitors(mutex, 2);
// Function future must not have commenced execution yet.
try {
functionFuture.awaitDone(100, TimeUnit.MILLISECONDS);
fail("timeout expected");
} catch (TimedOutError e) {
// NOOP
}
assertFalse(functionExecuted.get());
setupLatch.unblock();
functionFuture.awaitDone(5, TimeUnit.SECONDS);
assertTrue(functionExecuted.get());
assertFalse(future.isCancelled());
assertTrue(future.isDone());
assertFalse(functionFuture.isCancelled());
assertTrue(functionFuture.isDone());
}
use of org.eclipse.scout.rt.platform.util.concurrent.TimedOutError in project scout.rt by eclipse.
the class JobManagerLoadTest method testDelayedExecuting.
@Test(timeout = 20_000)
public void testDelayedExecuting() {
IFilter<IFuture<?>> filter = Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter();
Date startDate = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(3));
final AtomicLong counter = new AtomicLong();
for (int i = 0; i < JOB_COUNT; i++) {
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
counter.incrementAndGet();
}
}, Jobs.newInput().withExecutionHint(JOB_IDENTIFIER).withExecutionTrigger(Jobs.newExecutionTrigger().withStartAt(startDate)));
}
try {
Jobs.getJobManager().awaitDone(filter, 10, TimeUnit.SECONDS);
assertEquals(JOB_COUNT, counter.get());
} catch (TimedOutError e) {
Jobs.getJobManager().cancel(filter, true);
fail("Scheduling 25'000 took longer than 10s");
}
}
use of org.eclipse.scout.rt.platform.util.concurrent.TimedOutError in project scout.rt by eclipse.
the class JobScheduleTest method testScheduleWithTimeoutWithMutex.
@Test
public void testScheduleWithTimeoutWithMutex() {
final IExecutionSemaphore mutex = Jobs.newExecutionSemaphore(1);
final BlockingCountDownLatch latch = new BlockingCountDownLatch(1);
IFuture<String> future1 = Jobs.getJobManager().schedule(new Callable<String>() {
@Override
public String call() throws Exception {
latch.countDownAndBlock();
return "job-1";
}
}, Jobs.newInput().withRunContext(RunContexts.empty()).withExecutionSemaphore(mutex).withExceptionHandling(null, false));
IFuture<String> future2 = Jobs.getJobManager().schedule(new Callable<String>() {
@Override
public String call() throws Exception {
return "job-2";
}
}, Jobs.newInput().withRunContext(RunContexts.empty()).withExecutionSemaphore(mutex));
try {
assertEquals("job-2", future2.awaitDoneAndGet(2, TimeUnit.SECONDS));
fail("TimeoutException expected");
} catch (TimedOutError e) {
// NOOP
}
latch.unblock();
// wait for all jobs to complete
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchFuture(future1, future2).toFilter(), 10, TimeUnit.SECONDS);
}
use of org.eclipse.scout.rt.platform.util.concurrent.TimedOutError in project scout.rt by eclipse.
the class AwaitDoneTest method testAwaitDoneOrWaiting.
@Test
public void testAwaitDoneOrWaiting() {
// synchronized because modified/read by different threads.
final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
final IBlockingCondition condition = Jobs.newBlockingCondition(true);
IFuture<Void> future = Jobs.getJobManager().schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("before-1");
condition.waitFor();
protocol.add("after-2");
}
}, Jobs.newInput().withRunContext(RunContexts.copyCurrent()).withExceptionHandling(null, false));
try {
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchFuture(future).toFilter(), 100, TimeUnit.MILLISECONDS);
fail("timeout expected");
} catch (TimedOutError e) {
// NOOP
}
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchFuture(future).andMatchNotState(JobState.WAITING_FOR_BLOCKING_CONDITION).toFilter(), 10, TimeUnit.SECONDS);
assertEquals(Arrays.asList("before-1"), protocol);
// Cleanup
condition.setBlocking(false);
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchFuture(future).toFilter(), 10, TimeUnit.SECONDS);
}
Aggregations