Search in sources :

Example 31 with TimedOutError

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);
    }
}
Also used : SessionStoreMaxWaitWriteLockProperty(org.eclipse.scout.rt.ui.html.UiHtmlConfigProperties.SessionStoreMaxWaitWriteLockProperty) SessionStoreMaxWaitAllShutdownProperty(org.eclipse.scout.rt.ui.html.UiHtmlConfigProperties.SessionStoreMaxWaitAllShutdownProperty) ArrayList(java.util.ArrayList) IClientSession(org.eclipse.scout.rt.client.IClientSession) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) TimedOutError(org.eclipse.scout.rt.platform.util.concurrent.TimedOutError) IFuture(org.eclipse.scout.rt.platform.job.IFuture)

Example 32 with TimedOutError

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();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) TimedOutError(org.eclipse.scout.rt.platform.util.concurrent.TimedOutError) IBlockingCondition(org.eclipse.scout.rt.platform.job.IBlockingCondition) ProcessingException(org.eclipse.scout.rt.platform.exception.ProcessingException) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) Test(org.junit.Test)

Aggregations

TimedOutError (org.eclipse.scout.rt.platform.util.concurrent.TimedOutError)32 IRunnable (org.eclipse.scout.rt.platform.util.concurrent.IRunnable)20 Test (org.junit.Test)20 BlockingCountDownLatch (org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch)11 AssertionException (org.eclipse.scout.rt.platform.util.Assertions.AssertionException)9 ThreadInterruptedError (org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)8 ProcessingException (org.eclipse.scout.rt.platform.exception.ProcessingException)6 IFuture (org.eclipse.scout.rt.platform.job.IFuture)6 IExecutionSemaphore (org.eclipse.scout.rt.platform.job.IExecutionSemaphore)5 ArrayList (java.util.ArrayList)4 PlatformException (org.eclipse.scout.rt.platform.exception.PlatformException)4 IBlockingCondition (org.eclipse.scout.rt.platform.job.IBlockingCondition)4 Times (org.eclipse.scout.rt.testing.platform.runner.Times)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 JMSException (javax.jms.JMSException)3 NamingException (javax.naming.NamingException)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 JobCompletionDelayOnSessionShutdown (org.eclipse.scout.rt.client.ClientConfigProperties.JobCompletionDelayOnSessionShutdown)2