use of org.eclipse.scout.rt.platform.util.concurrent.IRunnable in project scout.rt by eclipse.
the class MultipleSessionTest method testCancel.
@Test
public void testCancel() throws InterruptedException {
// synchronized because modified/read by different threads.
final Set<String> protocol = Collections.synchronizedSet(new HashSet<String>());
final BlockingCountDownLatch setupLatch1 = new BlockingCountDownLatch(2);
final BlockingCountDownLatch setupLatch2 = new BlockingCountDownLatch(1);
final BlockingCountDownLatch interruptedJob1_S1_Latch = new BlockingCountDownLatch(1);
final BlockingCountDownLatch awaitAllCancelledLatch = new BlockingCountDownLatch(1);
// Session 1 (job1)
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job1-S1");
try {
setupLatch1.countDownAndBlock();
} catch (InterruptedException e) {
protocol.add("job1-S1-interrupted");
} finally {
interruptedJob1_S1_Latch.countDown();
}
// ensure the thread's interrupted status to be cleared in order to continue the test.
Thread.interrupted();
awaitAllCancelledLatch.await();
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession1, true)).withName("job-1-S1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
// Session 1 (job2) --> never starts running because cancelled while job1 is mutex-owner
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job2-S1");
try {
setupLatch2.countDownAndBlock();
} catch (InterruptedException e) {
protocol.add("job2-S1-interrupted");
}
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession1, true)).withName("job-2-S1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
// Session 2 (job1)
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job1-S2");
try {
setupLatch1.countDownAndBlock();
} catch (InterruptedException e) {
protocol.add("job1-S2-interrupted");
}
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession2, true)).withName("job-1-S2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
// Session 2 (job2)
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job2-S2");
try {
setupLatch2.countDownAndBlock();
} catch (InterruptedException e) {
protocol.add("job2-S2-interrupted");
}
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession2, true)).withName("job-2-S2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
assertTrue(setupLatch1.await());
assertEquals(CollectionUtility.hashSet("job1-S1", "job1-S2"), protocol);
Jobs.getJobManager().cancel(ModelJobs.newFutureFilterBuilder().andMatch(new SessionFutureFilter(m_clientSession1)).toFilter(), // cancels job-1-S1 and job-2-S1, meaning that job-2-S1 never starts running.
true);
awaitAllCancelledLatch.unblock();
assertTrue(interruptedJob1_S1_Latch.await());
setupLatch1.unblock();
assertTrue(setupLatch2.await());
assertEquals(CollectionUtility.hashSet("job1-S1", "job1-S1-interrupted", "job1-S2", "job2-S2"), protocol);
setupLatch2.unblock();
// Wait until all jobs completed
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter(), 10, TimeUnit.SECONDS);
}
use of org.eclipse.scout.rt.platform.util.concurrent.IRunnable in project scout.rt by eclipse.
the class MultipleSessionTest method testMutalExclusion.
@Test
public void testMutalExclusion() throws InterruptedException {
// synchronized because modified/read by different threads.
final Set<String> protocol = Collections.synchronizedSet(new HashSet<String>());
final BlockingCountDownLatch latch1 = new BlockingCountDownLatch(2);
final BlockingCountDownLatch latch2 = new BlockingCountDownLatch(2);
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job1-S1");
latch1.countDownAndBlock();
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession1, true)).withName("job-1-S1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job2-S1");
latch2.countDownAndBlock();
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession1, true)).withName("job-2-S1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job1-S2");
latch1.countDownAndBlock();
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession2, true)).withName("job-1-S2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job2-S2");
latch2.countDownAndBlock();
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(m_clientSession2, true)).withName("job-2-S2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
assertTrue(latch1.await());
assertEquals(CollectionUtility.hashSet("job1-S1", "job1-S2"), protocol);
latch1.unblock();
assertTrue(latch2.await());
assertEquals(CollectionUtility.hashSet("job1-S1", "job1-S2", "job2-S1", "job2-S2"), protocol);
latch2.unblock();
// Wait until all jobs completed
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter(), 10, TimeUnit.SECONDS);
}
use of org.eclipse.scout.rt.platform.util.concurrent.IRunnable in project scout.rt by eclipse.
the class MutualExclusionTest method runTestBlockingCondition.
private void runTestBlockingCondition(final IBlockingCondition condition) {
condition.setBlocking(true);
// synchronized because modified/read by different threads.
final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
final IFuture<?> iFuture1 = IFuture.CURRENT.get();
protocol.add("job-1-running");
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
final IFuture<?> iFuture2 = IFuture.CURRENT.get();
protocol.add("job-2-running");
if (iFuture1.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
protocol.add("job-1-blocked");
}
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-3-running");
if (iFuture1.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
protocol.add("job-1-blocked");
}
if (iFuture2.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
protocol.add("job-2-blocked");
}
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-4-running");
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER));
protocol.add("job-3-before-signaling");
condition.setBlocking(false);
// Wait for the other jobs to have tried re-acquiring the mutex.
JobTestUtil.waitForPermitCompetitors(m_clientSession.getModelJobSemaphore(), 4);
protocol.add("job-3-after-signaling");
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("job-5-running");
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER));
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER));
protocol.add("job-2-beforeAwait");
condition.waitFor();
protocol.add("JOB-X-AFTERAWAIT");
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER));
protocol.add("job-1-beforeAwait");
condition.waitFor();
protocol.add("JOB-X-AFTERAWAIT");
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER));
awaitDoneElseFail(JOB_IDENTIFIER);
List<String> expected = new ArrayList<>();
expected.add("job-1-running");
expected.add("job-1-beforeAwait");
expected.add("job-2-running");
expected.add("job-1-blocked");
expected.add("job-2-beforeAwait");
expected.add("job-3-running");
expected.add("job-1-blocked");
expected.add("job-2-blocked");
expected.add("job-3-before-signaling");
expected.add("job-3-after-signaling");
// no guarantee about the sequence in which waiting threads are released when the blocking condition falls.
expected.add("JOB-X-AFTERAWAIT");
// no guarantee about the sequence in which waiting threads are released when the blocking condition falls.
expected.add("JOB-X-AFTERAWAIT");
expected.add("job-4-running");
expected.add("job-5-running");
assertEquals(expected, protocol);
}
use of org.eclipse.scout.rt.platform.util.concurrent.IRunnable in project scout.rt by eclipse.
the class MutualExclusionTest method testAwaitDoneWithSameMutex.
@Test(expected = AssertionException.class, timeout = 5000)
public void testAwaitDoneWithSameMutex() {
final IExecutionSemaphore mutex = Jobs.newExecutionSemaphore(1);
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
// NOOP
}
}, Jobs.newInput().withExecutionSemaphore(mutex)).awaitDone();
}
}, Jobs.newInput().withExecutionSemaphore(mutex)).awaitDoneAndGet();
}
use of org.eclipse.scout.rt.platform.util.concurrent.IRunnable in project scout.rt by eclipse.
the class MutualExclusionTest method testExpiredWhenReAcquiringMutex.
/**
* Tests that a job continues execution after waiting for a blocking condition to fall.
*/
@Test
public void testExpiredWhenReAcquiringMutex() throws java.lang.InterruptedException {
// synchronized because modified/read by different threads.
final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
final IBlockingCondition condition = Jobs.newBlockingCondition(true);
final BlockingCountDownLatch latch = new BlockingCountDownLatch(1);
final int expirationTime = 100;
IFuture<Void> future = ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("1: running");
ModelJobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
protocol.add("2: running");
condition.setBlocking(false);
latch.countDownAndBlock();
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-2"));
condition.waitFor();
protocol.add("3: running");
}
}, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-1").withExceptionHandling(null, false).withExpirationTime(expirationTime, TimeUnit.MILLISECONDS));
// Wait until job-1 can re-acquire the mutex
assertTrue(latch.await());
// Wait until job-1 would be expired
SleepUtil.sleepSafe(expirationTime + 1, TimeUnit.MILLISECONDS);
latch.unblock();
// Expect the job to continue running.
future.awaitDoneAndGet(5, TimeUnit.SECONDS);
List<String> expected = new ArrayList<>();
expected.add("1: running");
expected.add("2: running");
expected.add("3: running");
assertEquals(expected, protocol);
}
Aggregations