use of org.eclipse.scout.rt.shared.job.filter.future.SessionFutureFilter 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.shared.job.filter.future.SessionFutureFilter in project scout.rt by eclipse.
the class AbstractClientSession method cancelRunningJobs.
protected void cancelRunningJobs() {
// Filter matches all running jobs that have the same client session associated, except the current thread
// and model jobs. Because the current thread is (or should be) a model job, we cannot wait for other
// model threads. They are always cancelled.
IFilter<IFuture<?>> runningJobsFilter = Jobs.newFutureFilterBuilder().andMatch(new SessionFutureFilter(ISession.CURRENT.get())).andMatchNotFuture(IFuture.CURRENT.get()).andMatchNot(ModelJobFutureFilter.INSTANCE).andMatchNotState(JobState.DONE, JobState.REJECTED).toFilter();
// Wait for running jobs to complete before we cancel them
long delay = NumberUtility.nvl(CONFIG.getPropertyValue(JobCompletionDelayOnSessionShutdown.class), 0L);
if (delay > 0L) {
try {
Jobs.getJobManager().awaitDone(runningJobsFilter, delay, TimeUnit.SECONDS);
} catch (TimedOutError e) {
// NOSONAR
// NOP (not all jobs have been finished within the delay)
} catch (ThreadInterruptedError e) {
LOG.warn("Failed to await for running jobs to complete.", e);
}
}
// Cancel remaining jobs and write a warning to the logger
Set<IFuture<?>> runningFutures = Jobs.getJobManager().getFutures(runningJobsFilter);
if (!runningFutures.isEmpty()) {
LOG.warn("Some running client jobs found while stopping the client session; sent a cancellation request to release associated worker threads. [session={}, user={}, jobs={}]", AbstractClientSession.this, getUserId(), runningFutures);
Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder().andMatchFuture(runningFutures).toFilter(), true);
}
// Now cancel all other model jobs. Because the current thread is a model job, they can never run anyway.
Set<IFuture<?>> runningModelJobs = Jobs.getJobManager().getFutures(Jobs.newFutureFilterBuilder().andMatch(new SessionFutureFilter(ISession.CURRENT.get())).andMatchNotFuture(IFuture.CURRENT.get()).andMatch(ModelJobFutureFilter.INSTANCE).andMatchNotState(JobState.DONE, JobState.REJECTED).toFilter());
if (!runningModelJobs.isEmpty()) {
LOG.info("Cancel running model jobs because the client session was shut down. [session={}, user={}, jobs={}]", AbstractClientSession.this, getUserId(), runningModelJobs);
Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder().andMatchFuture(runningModelJobs).toFilter(), true);
}
}
use of org.eclipse.scout.rt.shared.job.filter.future.SessionFutureFilter in project scout.rt by eclipse.
the class AbstractServerSession method stop.
@Override
public void stop() {
fireSessionChangedEvent(new SessionEvent(this, SessionEvent.TYPE_STOPPING));
m_active = false;
fireSessionChangedEvent(new SessionEvent(this, SessionEvent.TYPE_STOPPED));
// Cancel globally registered RunMonitors of this session.
BEANS.get(RunMonitorCancelRegistry.class).cancelAllBySessionId(getId());
// Cancel running jobs of this session.
Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder().andMatch(new SessionFutureFilter(this)).andMatchNotFuture(IFuture.CURRENT.get()).toFilter(), true);
LOG.info("Server session stopped [session={}, user={}]", this, getUserId());
}
use of org.eclipse.scout.rt.shared.job.filter.future.SessionFutureFilter in project scout.rt by eclipse.
the class SessionFutureFilterTest method test.
@Test
public void test() {
IServerSession session1 = mock(IServerSession.class);
IServerSession session2 = mock(IServerSession.class);
SessionFutureFilter filter = new SessionFutureFilter(session1);
// Tests a Future of a job without RunContext
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput())));
// Tests a Future of a job with RunContext
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(RunContexts.empty()))));
// Tests a Future of a job with ClientRunContext without session
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty()))));
// Tests a Future of a job with ClientRunContext with correct session
assertTrue(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty().withSession(session1)))));
// Tests a Future of a job with ClientRunContext with wrong session
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty().withSession(session2)))));
// Test adaptable to the session
assertSame(session1, filter.getAdapter(ISession.class));
}
use of org.eclipse.scout.rt.shared.job.filter.future.SessionFutureFilter in project scout.rt by eclipse.
the class SessionFutureFilterTest method test.
@Test
public void test() {
IClientSession session1 = mock(IClientSession.class);
IClientSession session2 = mock(IClientSession.class);
SessionFutureFilter filter = new SessionFutureFilter(session1);
// Tests a Future of a job without RunContext
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput())));
// Tests a Future of a job with RunContext
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(RunContexts.empty()))));
// Tests a Future of a job with ClientRunContext without session
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty()))));
// Tests a Future of a job with ClientRunContext with correct session
assertTrue(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(session1, false)))));
// Tests a Future of a job with ClientRunContext with wrong session
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(session2, false)))));
// Test adaptable to the session
assertSame(session1, filter.getAdapter(ISession.class));
}
Aggregations