Search in sources :

Example 31 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class FutureAwaitTest method testAwaitDoneAndGetWithTimeout_Interrupted.

@Test(timeout = 5000)
public void testAwaitDoneAndGetWithTimeout_Interrupted() throws java.lang.InterruptedException {
    final BlockingCountDownLatch setupLatch = new BlockingCountDownLatch(1);
    // Init
    final IFuture<String> future = Jobs.schedule(new Callable<String>() {

        @Override
        public String call() throws Exception {
            setupLatch.countDownAndBlock();
            return "result";
        }
    }, Jobs.newInput().withRunContext(RunContexts.copyCurrent()));
    // Run the test in a separate thread
    IFuture<Void> controller = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            Thread.currentThread().interrupt();
            try {
                future.awaitDoneAndGet(10, TimeUnit.SECONDS);
                fail("interruption expected");
            } catch (ThreadInterruptedError e) {
                assertTrue(Thread.currentThread().isInterrupted());
            }
        }
    }, Jobs.newInput());
    controller.awaitDoneAndGet(10, TimeUnit.SECONDS);
    setupLatch.unblock();
    future.awaitDone(10, TimeUnit.SECONDS);
}
Also used : BlockingCountDownLatch(org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) Test(org.junit.Test)

Example 32 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class SessionStore method doHousekeeping.

/**
 * Checks if the client session is still used by a UI session. If not, it is stopped and removed form the store.
 */
protected void doHousekeeping(final IClientSession clientSession) {
    m_writeLock.lock();
    try {
        if (IFuture.CURRENT.get().isCancelled()) {
            return;
        }
        m_housekeepingFutures.remove(clientSession.getId());
        if (!clientSession.isActive() || clientSession.isStopping()) {
            LOG.info("Session housekeeping: Client session {} is {}, removing it from store", clientSession.getId(), (!clientSession.isActive() ? "inactive" : "stopping"));
            removeClientSession(clientSession);
            return;
        }
        // Check if the client session is referenced by any UI session
        Set<IUiSession> uiSessions = m_uiSessionsByClientSession.get(clientSession);
        LOG.debug("Session housekeeping: Client session {} referenced by {} UI sessions", clientSession.getId(), (uiSessions == null ? 0 : uiSessions.size()));
        if (uiSessions == null || uiSessions.isEmpty()) {
            LOG.info("Session housekeeping: Shutting down client session with ID {} because it is not used anymore", clientSession.getId());
            try {
                final IFuture<Void> future = ModelJobs.schedule(new IRunnable() {

                    @Override
                    public void run() throws Exception {
                        forceClientSessionShutdown(clientSession);
                    }
                }, ModelJobs.newInput(ClientRunContexts.empty().withSession(clientSession, true)).withName("Force shutting down client session {} by session housekeeping", clientSession.getId()));
                int timeout = CONFIG.getPropertyValue(SessionStoreHousekeepingMaxWaitShutdownProperty.class).intValue();
                try {
                    // NOSONAR
                    future.awaitDone(timeout, TimeUnit.SECONDS);
                } catch (TimedOutError e) {
                    // NOSONAR
                    LOG.warn("Client session did no stop within {} seconds. Canceling shutdown job.", timeout);
                    future.cancel(true);
                }
            } catch (ThreadInterruptedError e) {
                LOG.warn("Interruption encountered while waiting for client session {} to stop. Continuing anyway.", clientSession.getId(), e);
            } finally {
                removeClientSession(clientSession);
            }
        }
    } finally {
        m_writeLock.unlock();
    }
}
Also used : SessionStoreHousekeepingMaxWaitShutdownProperty(org.eclipse.scout.rt.ui.html.UiHtmlConfigProperties.SessionStoreHousekeepingMaxWaitShutdownProperty) 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)

Example 33 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError 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 34 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class UiSession method processFileUpload.

@Override
public JSONObject processFileUpload(HttpServletRequest req, HttpServletResponse res, final IBinaryResourceConsumer resourceConsumer, final List<BinaryResource> uploadResources, final Map<String, String> uploadProperties) {
    final ClientRunContext clientRunContext = ClientRunContexts.copyCurrent().withSession(m_clientSession, true);
    m_httpContext.set(req, res);
    try {
        m_processingJsonRequest = true;
        try {
            // 1. Process the JSON request.
            ModelJobs.schedule(new IRunnable() {

                @Override
                public void run() throws Exception {
                    resourceConsumer.consumeBinaryResource(uploadResources, uploadProperties);
                }
            }, createFileUploadModelJobInput(clientRunContext));
            // 2. Wait for all model jobs of the session.
            BEANS.get(UiJobs.class).awaitModelJobs(m_clientSession, ExceptionHandler.class);
        } finally {
            // Reset this flag _before_ the "response-to-json" job (#3), because writing to the response while transforming would be unsafe and unreliable.
            m_processingJsonRequest = false;
        }
        // 3. Transform the response to JSON.
        final IFuture<JSONObject> future = ModelJobs.schedule(newResponseToJsonTransformer(), ModelJobs.newInput(clientRunContext.copy().withRunMonitor(// separate RunMonitor to not cancel 'response-to-json' job once processing is cancelled
        BEANS.get(RunMonitor.class))).withName("Transforming response to JSON").withExecutionHint(UiJobs.EXECUTION_HINT_RESPONSE_TO_JSON).withExceptionHandling(null, // Propagate exception to caller (UIServlet)
        false));
        try {
            return BEANS.get(UiJobs.class).awaitAndGet(future);
        } catch (ThreadInterruptedError e) {
            // NOSONAR
            future.cancel(true);
            return null;
        } catch (FutureCancelledError e) {
            // NOSONAR
            return null;
        }
    } finally {
        m_httpContext.clear();
        if (m_disposing) {
            dispose();
        }
    }
}
Also used : ClientRunContext(org.eclipse.scout.rt.client.context.ClientRunContext) JSONObject(org.json.JSONObject) FutureCancelledError(org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable)

Example 35 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class UiSession method processJsonRequest.

@Override
public JSONObject processJsonRequest(final HttpServletRequest servletRequest, final HttpServletResponse servletResponse, final JsonRequest jsonRequest) {
    if (isAlreadyProcessed(jsonRequest)) {
        JSONObject response = m_responseHistory.getResponseForRequest(jsonRequest.getSequenceNo());
        LOG.debug("Request #{} was already processed. Sending back response from history.", jsonRequest.getSequenceNo());
        return response;
    }
    final ClientRunContext clientRunContext = ClientRunContexts.copyCurrent().withSession(m_clientSession, true);
    m_httpContext.set(servletRequest, servletResponse);
    m_currentJsonRequest = jsonRequest;
    try {
        m_processingJsonRequest = true;
        try {
            // 1. Process the JSON request.
            ModelJobs.schedule(new IRunnable() {

                @Override
                public void run() throws Exception {
                    processJsonRequestInternal();
                }
            }, createJsonRequestModelJobInput(jsonRequest, clientRunContext));
            // 2. Wait for all model jobs of the session.
            BEANS.get(UiJobs.class).awaitModelJobs(m_clientSession, ExceptionHandler.class);
        } finally {
            // Reset this flag _before_ the "response-to-json" job (#3), because writing to the response while transforming would be unsafe and unreliable.
            m_processingJsonRequest = false;
        }
        // 3. Transform the response to JSON.
        final IFuture<JSONObject> future = ModelJobs.schedule(newResponseToJsonTransformer(), ModelJobs.newInput(clientRunContext.copy().withRunMonitor(// separate RunMonitor to not cancel 'response-to-json' job once processing is cancelled
        BEANS.get(RunMonitor.class))).withName("Transforming response to JSON").withExecutionHint(UiJobs.EXECUTION_HINT_RESPONSE_TO_JSON).withExecutionHint(UiJobs.EXECUTION_HINT_POLL_REQUEST, jsonRequest.getRequestType() == RequestType.POLL_REQUEST).withExceptionHandling(null, // Propagate exception to caller (UIServlet)
        false));
        try {
            return BEANS.get(UiJobs.class).awaitAndGet(future);
        } catch (ThreadInterruptedError e) {
            // NOSONAR
            future.cancel(true);
            return null;
        } catch (FutureCancelledError e) {
            // NOSONAR
            return null;
        }
    } finally {
        setRequestProcessed(jsonRequest);
        m_httpContext.clear();
        m_currentJsonRequest = null;
        if (m_disposing) {
            dispose();
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Adapter count after request: {}", m_jsonAdapterRegistry.size());
        }
    }
}
Also used : JSONObject(org.json.JSONObject) ClientRunContext(org.eclipse.scout.rt.client.context.ClientRunContext) FutureCancelledError(org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError) RunMonitor(org.eclipse.scout.rt.platform.context.RunMonitor) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable)

Aggregations

ThreadInterruptedError (org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)36 IRunnable (org.eclipse.scout.rt.platform.util.concurrent.IRunnable)20 Test (org.junit.Test)14 BlockingCountDownLatch (org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch)13 TimedOutError (org.eclipse.scout.rt.platform.util.concurrent.TimedOutError)8 FutureCancelledError (org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError)7 AssertionException (org.eclipse.scout.rt.platform.util.Assertions.AssertionException)5 ArrayList (java.util.ArrayList)4 ProcessingException (org.eclipse.scout.rt.platform.exception.ProcessingException)4 ClientRunContext (org.eclipse.scout.rt.client.context.ClientRunContext)3 PlatformException (org.eclipse.scout.rt.platform.exception.PlatformException)3 IBlockingCondition (org.eclipse.scout.rt.platform.job.IBlockingCondition)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 JMSException (javax.jms.JMSException)2 NamingException (javax.naming.NamingException)2 IClientSession (org.eclipse.scout.rt.client.IClientSession)2 IMessageBox (org.eclipse.scout.rt.client.ui.messagebox.IMessageBox)2 RunMonitor (org.eclipse.scout.rt.platform.context.RunMonitor)2 VetoException (org.eclipse.scout.rt.platform.exception.VetoException)2