use of org.eclipse.scout.rt.platform.util.concurrent.TimedOutError 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.util.concurrent.TimedOutError in project scout.rt by eclipse.
the class MutualExclusionTest method testAwaitDoneWithSameMutexButNotMutexOwner.
/**
* A mutual exclusive job is running, and passes the mutex via BlockingCondition.waitFor() to the next task. But the
* blocking condition is never unblocked, which results in a timeout. However, the job re-acquires the mutex anew
* before continuing.<br/>
* Tests, that the job is the mutex owner after the timeout, and that it cannot wait for another model job to
* complete.
*/
@Test(timeout = 5000)
public void testAwaitDoneWithSameMutexButNotMutexOwner() {
final IExecutionSemaphore mutex = Jobs.newExecutionSemaphore(1);
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
IBlockingCondition bc = Jobs.newBlockingCondition(true);
try {
bc.waitFor(1, TimeUnit.SECONDS);
fail("timeout expected");
} catch (TimedOutError e) {
assertTrue(IFuture.CURRENT.get().getExecutionSemaphore().isPermitOwner(IFuture.CURRENT.get()));
try {
final AtomicBoolean run = new AtomicBoolean(false);
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
run.set(true);
}
}, Jobs.newInput().withExecutionSemaphore(mutex)).awaitDone(1, TimeUnit.SECONDS);
fail("AssertionException expected, because the current job is the mutex owner");
} catch (TimedOutError e1) {
fail("no timeout expected");
} catch (AssertionException e1) {
// NOOP: OK
}
}
}
}, Jobs.newInput().withExecutionSemaphore(mutex)).awaitDoneAndGet();
}
Aggregations