use of org.eclipse.scout.rt.platform.job.IFuture in project scout.rt by eclipse.
the class MutexFutureFilterTest method test.
@Test
public void test() {
IExecutionSemaphore mutex1 = Jobs.newExecutionSemaphore(1);
IExecutionSemaphore mutex2 = Jobs.newExecutionSemaphore(1);
IFuture<Void> future1 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withExecutionSemaphore(mutex1));
IFuture<Void> future2 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withExecutionSemaphore(mutex1));
IFuture<Void> future3 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withExecutionSemaphore(mutex2));
IFilter<IFuture<?>> filter = new ExecutionSemaphoreFutureFilter(mutex1);
assertTrue(filter.accept(future1));
assertTrue(filter.accept(future2));
assertFalse(filter.accept(future3));
}
use of org.eclipse.scout.rt.platform.job.IFuture in project scout.rt by eclipse.
the class SessionStore method valueUnbound.
@Override
public void valueUnbound(final HttpSessionBindingEvent event) {
if (!m_httpSessionValid) {
// valueUnbound() has already been executed
return;
}
m_httpSessionValid = false;
LOG.info("Detected invalidation of HTTP session {}, cleaning up {} client sessions and {} UI sessions", m_httpSessionId, m_clientSessionMap.size(), m_uiSessionMap.size());
final List<IFuture<?>> futures = new ArrayList<>();
// Stop all client sessions (in parallel model jobs)
try {
int timeout = CONFIG.getPropertyValue(SessionStoreMaxWaitWriteLockProperty.class).intValue();
if (m_writeLock.tryLock(timeout, TimeUnit.SECONDS)) {
try {
for (final IClientSession clientSession : m_clientSessionMap.values()) {
futures.add(ModelJobs.schedule(new IRunnable() {
@Override
public void run() {
LOG.debug("Shutting down client session with ID {} due to invalidation of HTTP session", clientSession.getId());
forceClientSessionShutdown(clientSession);
removeClientSession(clientSession);
}
}, ModelJobs.newInput(ClientRunContexts.empty().withSession(clientSession, true)).withName("Closing desktop due to HTTP session invalidation")));
}
} finally {
m_writeLock.unlock();
}
} else {
LOG.warn("Could not acquire write lock within {} seconds: [HTTP session: {}, uiSessionMap: {}, clientSessionMap: {}, uiSessionsByClientSession: {}]", timeout, m_uiSessionMap.size(), m_clientSessionMap.size(), m_uiSessionsByClientSession.size());
}
} catch (InterruptedException e) {
LOG.warn("Interrupted while waiting on session store write lock", e);
}
if (futures.isEmpty()) {
return;
}
LOG.debug("Waiting for {} client sessions to stop...", futures.size());
try {
// Wait for all client sessions to stop. This is done in sync to ensure the session is not invalidated before the attached scout session has been stopped.
// Otherwise we would have a running scout session on an invalidated http session.
// Furthermore: on webapp shutdown we must first stop all sessions (scout and http) before we stop the platform. Therefore the stop must be sync!
Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchFuture(futures).toFilter(), CONFIG.getPropertyValue(SessionStoreMaxWaitAllShutdownProperty.class), TimeUnit.SECONDS);
LOG.info("Session shutdown complete.");
} catch (ThreadInterruptedError e) {
LOG.warn("Interruption encountered while waiting for all client session to stop. Continuing anyway.", e);
} catch (TimedOutError e) {
LOG.warn("Timeout encountered while waiting for all client session to stop. Canceling still running client session shutdown jobs.", e);
// timeout while waiting for the sessions to stop. Force cancel them.
Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder().andMatchFuture(futures).andMatchNotState(JobState.DONE).toFilter(), true);
}
// Check if everything was cleaned up correctly ("leak detection").
// Read map sizes outside a lock - dirty reads are acceptable here
final int uiSessionMapSize = m_uiSessionMap.size();
final int clientSessionMapSize = m_clientSessionMap.size();
final int uiSessionsByClientSessionSize = m_uiSessionsByClientSession.size();
if (uiSessionMapSize + clientSessionMapSize + uiSessionsByClientSessionSize > 0) {
LOG.warn("Leak detection - Session store not empty after HTTP session invalidation: [uiSessionMap: {}, clientSessionMap: {}, uiSessionsByClientSession: {}]", uiSessionMapSize, clientSessionMapSize, uiSessionsByClientSessionSize);
}
}
use of org.eclipse.scout.rt.platform.job.IFuture in project scout.rt by eclipse.
the class DownloadHandlerStorage method removeOnTimeout.
protected void removeOnTimeout(String key) {
synchronized (m_valueMap) {
m_valueMap.remove(key);
IFuture future = m_futureMap.remove(key);
if (future != null && !future.isCancelled()) {
future.cancel(false);
}
}
}
use of org.eclipse.scout.rt.platform.job.IFuture in project scout.rt by eclipse.
the class ModelJobFutureFilterTest method test.
@Test
public void test() {
IClientSession session1 = mock(IClientSession.class);
when(session1.getModelJobSemaphore()).thenReturn(Jobs.newExecutionSemaphore(1));
IClientSession session2 = mock(IClientSession.class);
when(session2.getModelJobSemaphore()).thenReturn(Jobs.newExecutionSemaphore(1));
IFilter<IFuture<?>> filter = ModelJobFutureFilter.INSTANCE;
// not a model job (no Future)
assertFalse(filter.accept(null));
// not a model job (no ClientRunContext)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput())));
// not a model job (no ClientRunContext)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(RunContexts.empty()))));
// not a model job (no mutex and not session on ClientRunContext)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty()))));
// not a model job (no mutex)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(session1, false)))));
// not a model job (wrong mutex type)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(session1, false)).withExecutionSemaphore(Jobs.newExecutionSemaphore(1)))));
// not a model job (different session on ClientRunContext and mutex)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(session1, false)).withExecutionSemaphore(session2.getModelJobSemaphore()))));
// not a model job (no session on ClientRunContext)
assertFalse(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(null, false)).withExecutionSemaphore(session1.getModelJobSemaphore()))));
// this is a model job (same session on ClientRunContext and mutex)
assertTrue(filter.accept(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ClientRunContexts.empty().withSession(session1, false)).withExecutionSemaphore(session1.getModelJobSemaphore()))));
}
Aggregations