Search in sources :

Example 21 with ThreadInterruptedError

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

the class JmsMomImplementorTest method testRequestReplyCancellationInternal.

private void testRequestReplyCancellationInternal(final IBiDestination<String, String> destination) throws InterruptedException {
    final CountDownLatch neverLatch = new CountDownLatch(1);
    final CountDownLatch setupLatch = new CountDownLatch(1);
    final CountDownLatch verifyLatch = new CountDownLatch(2);
    final AtomicBoolean requestorInterrupted = new AtomicBoolean();
    final AtomicBoolean replierInterrupted = new AtomicBoolean();
    final AtomicBoolean replierCancelled = new AtomicBoolean();
    // Subscribe for the destination
    m_disposables.add(MOM.reply(JmsTestMom.class, destination, new IRequestListener<String, String>() {

        @Override
        public String onRequest(IMessage<String> request) {
            setupLatch.countDown();
            try {
                neverLatch.await();
            } catch (InterruptedException e) {
                replierInterrupted.set(true);
            } finally {
                replierCancelled.set(RunMonitor.CURRENT.get().isCancelled());
                verifyLatch.countDown();
            }
            return request.getTransferObject().toUpperCase();
        }
    }));
    // Initiate 'request-reply' communication
    final FinalValue<String> testee = new FinalValue<>();
    IFuture<Void> requestFuture = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            try {
                String result = MOM.request(JmsTestMom.class, destination, "hello world");
                testee.set(result);
            } catch (ThreadInterruptedError e) {
                requestorInterrupted.set(true);
            } finally {
                verifyLatch.countDown();
            }
        }
    }, Jobs.newInput().withName("initiator").withExecutionHint(m_testJobExecutionHint));
    // Wait until reply message processing started
    setupLatch.await();
    // Cancel the publishing thread
    requestFuture.cancel(true);
    // wait for request / reply interrupted
    verifyLatch.await();
    // Verify
    assertTrue(requestorInterrupted.get());
    assertTrue(replierInterrupted.get());
    assertTrue(replierCancelled.get());
    assertFalse(testee.isSet());
}
Also used : FinalValue(org.eclipse.scout.rt.platform.util.FinalValue) IRequestListener(org.eclipse.scout.rt.mom.api.IRequestListener) IMessage(org.eclipse.scout.rt.mom.api.IMessage) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) CountDownLatch(java.util.concurrent.CountDownLatch) BlockingCountDownLatch(org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch) PlatformException(org.eclipse.scout.rt.platform.exception.PlatformException) ProcessingException(org.eclipse.scout.rt.platform.exception.ProcessingException) NamingException(javax.naming.NamingException) JMSException(javax.jms.JMSException) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) VetoException(org.eclipse.scout.rt.platform.exception.VetoException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 22 with ThreadInterruptedError

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

the class JmsMomImplementor method request.

@Override
public <REQUEST, REPLY> REPLY request(final IBiDestination<REQUEST, REPLY> destination, final REQUEST requestObject, final PublishInput input) {
    assertTrue(m_requestReplyEnabled, "'request-reply' messaging is not enabled for this MOM");
    assertNotNull(destination, "destination not specified");
    assertNotNull(input, "publishInput not specified");
    assertFalse(input.isTransactional(), "transactional mode not supported for 'request-reply' communication");
    // JMS message ID not applicable because unknown until sent
    final String replyId = String.format("scout.mom.requestreply.uid-%s", UUID.randomUUID());
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    IFuture<Message> requestFuture = Jobs.schedule(new Callable<Message>() {

        @Override
        public Message call() throws Exception {
            try {
                return requestImpl(destination, requestObject, input, replyId);
            } finally {
                condition.setBlocking(false);
            }
        }
    }, newJobInput().withName("request on {}", destination.getName()).withExceptionHandling(BEANS.get(MomExceptionHandler.class), false).withRunContext(RunContexts.copyCurrent(true).withDiagnostics(BEANS.all(IJmsRunContextDiagnostics.class))));
    try {
        long timeout = input.getRequestReplyTimeout();
        if (timeout == PublishInput.INFINITELY) {
            condition.waitFor();
        } else {
            condition.waitFor(timeout, TimeUnit.MILLISECONDS);
        }
        Message responseMessage = requestFuture.awaitDoneAndGet();
        return transform(responseMessage, replyId, resolveMarshaller(destination));
    } catch (JMSException e) {
        throw BEANS.get(DefaultRuntimeExceptionTranslator.class).translate(e);
    } catch (ThreadInterruptedError | TimedOutError e) {
        // send cancel to replier
        cancelRequest(replyId);
        // cancel request job
        if (requestFuture.cancel(true)) {
            requestFuture.awaitDone();
        }
        throw e;
    }
}
Also used : Message(javax.jms.Message) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) JMSException(javax.jms.JMSException) TimedOutError(org.eclipse.scout.rt.platform.util.concurrent.TimedOutError) ProcessingException(org.eclipse.scout.rt.platform.exception.ProcessingException) NamingException(javax.naming.NamingException) JMSException(javax.jms.JMSException) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) PlatformException(org.eclipse.scout.rt.platform.exception.PlatformException) IBlockingCondition(org.eclipse.scout.rt.platform.job.IBlockingCondition)

Example 23 with ThreadInterruptedError

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

the class HttpServiceTunnel method tunnel.

@Override
protected ServiceTunnelResponse tunnel(final ServiceTunnelRequest serviceRequest) {
    final long requestSequence = serviceRequest.getRequestSequence();
    // Create the Callable to be given to the job manager for execution.
    final RemoteServiceInvocationCallable remoteInvocationCallable = createRemoteServiceInvocationCallable(serviceRequest);
    // Register the execution monitor as child monitor of the current monitor so that the service request is cancelled once the current monitor gets cancelled.
    // Invoke the service operation asynchronously (to enable cancellation) and wait until completed or cancelled.
    final IFuture<ServiceTunnelResponse> future = Jobs.schedule(remoteInvocationCallable, Jobs.newInput().withRunContext(RunContext.CURRENT.get().copy()).withName(createServiceRequestName(requestSequence)).withExceptionHandling(null, // do not handle uncaught exceptions because typically invoked from within a model job (might cause a deadlock, because ClientExceptionHandler schedules and waits for a model job to visualize the exception).
    false)).whenDone(new IDoneHandler<ServiceTunnelResponse>() {

        @Override
        public void onDone(DoneEvent<ServiceTunnelResponse> event) {
            if (event.isCancelled()) {
                remoteInvocationCallable.cancel();
            }
        }
    }, RunContext.CURRENT.get().copy().withRunMonitor(// separate monitor to not cancel this cancellation action.
    BEANS.get(RunMonitor.class)));
    try {
        return future.awaitDoneAndGet();
    } catch (ThreadInterruptedError e) {
        // NOSONAR
        // Ensure the monitor to be cancelled once this thread is interrupted to cancel the remote call.
        future.cancel(true);
        // Interruption has precedence over computation result or computation error.
        return new ServiceTunnelResponse(new ThreadInterruptedError(TEXTS.get("UserInterrupted")));
    } catch (FutureCancelledError e) {
        // Cancellation has precedence over computation result or computation error.
        return new ServiceTunnelResponse(new FutureCancelledError(TEXTS.get("UserInterrupted")));
    }
}
Also used : FutureCancelledError(org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) ServiceTunnelResponse(org.eclipse.scout.rt.shared.servicetunnel.ServiceTunnelResponse)

Example 24 with ThreadInterruptedError

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

the class RemoteServiceInvocationCallable method call.

/**
 * Invokes the remote service operation.
 *
 * @return {@link IServiceTunnelResponse}; is never <code>null</code>.
 */
@Override
public ServiceTunnelResponse call() throws Exception {
    long nBytes = 0;
    final long tStart = LOG.isDebugEnabled() ? System.nanoTime() : 0L;
    try {
        // Create the request.
        final ByteArrayOutputStream requestMessage = new ByteArrayOutputStream();
        m_tunnel.getContentHandler().writeRequest(requestMessage, m_serviceRequest);
        requestMessage.close();
        final byte[] requestData = requestMessage.toByteArray();
        nBytes = requestData.length;
        // Send the request to the server.
        HttpResponse resp = m_tunnel.executeRequest(m_serviceRequest, requestData);
        // Receive the response.
        m_tunnel.interceptHttpResponse(resp, m_serviceRequest);
        if (resp.getStatusCode() != 0 && (resp.getStatusCode() < 200 || resp.getStatusCode() > 299)) {
            // request failed
            return new ServiceTunnelResponse(new HttpException(resp.getStatusCode()));
        }
        try (InputStream in = resp.getContent()) {
            return m_tunnel.getContentHandler().readResponse(in);
        }
    } catch (IOException e) {
        if (Thread.currentThread().isInterrupted()) {
            LOG.debug("Ignoring IOException for interrupted thread.", e);
            return new ServiceTunnelResponse(new ThreadInterruptedError("Thread is interrupted.", e));
        } else if (RunMonitor.CURRENT.get().isCancelled()) {
            LOG.debug("Ignoring IOException for cancelled thread.", e);
            return new ServiceTunnelResponse(new FutureCancelledError("RunMonitor is cancelled.", e));
        }
        throw e;
    } finally {
        if (LOG.isDebugEnabled()) {
            final long elapsedMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - tStart);
            LOG.debug("TIME {}.{} {}ms {} bytes", m_serviceRequest.getServiceInterfaceClassName(), m_serviceRequest.getOperation(), elapsedMillis, nBytes);
        }
    }
}
Also used : InputStream(java.io.InputStream) FutureCancelledError(org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError) HttpResponse(com.google.api.client.http.HttpResponse) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) HttpException(org.eclipse.scout.rt.shared.servicetunnel.HttpException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ServiceTunnelResponse(org.eclipse.scout.rt.shared.servicetunnel.ServiceTunnelResponse)

Example 25 with ThreadInterruptedError

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

the class JobStateTest method testBlockedAndInterrupted.

@Test
// regression
@Times(100)
public void testBlockedAndInterrupted() throws ThreadInterruptedError, java.lang.InterruptedException {
    JobEventCaptureListener captureListener = new JobEventCaptureListener();
    Jobs.getJobManager().addListener(captureListener);
    final IExecutionSemaphore mutex = Jobs.newExecutionSemaphore(1);
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    final AtomicReference<Thread> workerThread = new AtomicReference<>();
    final IFuture<Void> future1 = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            workerThread.set(Thread.currentThread());
            assertSame(JobState.RUNNING, IFuture.CURRENT.get().getState());
            try {
                condition.waitFor("ABC");
                fail("interruption expected");
            } catch (ThreadInterruptedError e) {
                assertTrue(Thread.interrupted());
                // Restore interrupted status
                Thread.currentThread().interrupt();
                assertTrue(mutex.isPermitOwner(IFuture.CURRENT.get()));
                assertSame(JobState.RUNNING, IFuture.CURRENT.get().getState());
            }
        }
    }, Jobs.newInput().withName("job-1").withExecutionSemaphore(mutex));
    // Wait until job-1 is running
    JobTestUtil.waitForState(future1, JobState.WAITING_FOR_BLOCKING_CONDITION);
    // Interrupt worker thread
    workerThread.get().interrupt();
    future1.awaitDoneAndGet();
    assertTrue(future1.isDone());
    assertFalse(future1.isCancelled());
    // wait because permit is released just after done (max 30s)
    JobTestUtil.waitForPermitCompetitors(mutex, 0);
    // verify events
    int i = -1;
    List<JobEvent> capturedEvents = captureListener.getCapturedEvents();
    List<JobState> capturedFutureStates = captureListener.getCapturedFutureStates();
    i++;
    assertStateChangedEvent(future1, JobState.SCHEDULED, capturedEvents.get(i));
    assertEquals(JobState.SCHEDULED, capturedFutureStates.get(i));
    i++;
    assertStateChangedEvent(future1, JobState.WAITING_FOR_PERMIT, capturedEvents.get(i));
    assertEquals(JobState.WAITING_FOR_PERMIT, capturedFutureStates.get(i));
    i++;
    assertStateChangedEvent(future1, JobState.RUNNING, capturedEvents.get(i));
    assertEquals(JobState.RUNNING, capturedFutureStates.get(i));
    i++;
    assertHintChangedEvent(JobEventType.JOB_EXECUTION_HINT_ADDED, future1, "ABC", capturedEvents.get(i));
    assertEquals(JobState.RUNNING, capturedFutureStates.get(i));
    i++;
    assertBlockedStateEvent(future1, condition, capturedEvents.get(i));
    assertEquals(JobState.WAITING_FOR_BLOCKING_CONDITION, capturedFutureStates.get(i));
    i++;
    assertStateChangedEvent(future1, JobState.WAITING_FOR_PERMIT, capturedEvents.get(i));
    assertEquals(JobState.WAITING_FOR_PERMIT, capturedFutureStates.get(i));
    i++;
    assertHintChangedEvent(JobEventType.JOB_EXECUTION_HINT_REMOVED, future1, "ABC", capturedEvents.get(i));
    assertEquals(JobState.WAITING_FOR_PERMIT, capturedFutureStates.get(i));
    i++;
    // due to interruption
    assertStateChangedEvent(future1, JobState.RUNNING, capturedEvents.get(i));
    assertEquals(JobState.RUNNING, capturedFutureStates.get(i));
    i++;
    assertStateChangedEvent(future1, JobState.DONE, capturedEvents.get(i));
    assertEquals(JobState.DONE, capturedFutureStates.get(i));
    assertEquals(i + 1, capturedEvents.size());
}
Also used : ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) AtomicReference(java.util.concurrent.atomic.AtomicReference) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) JobEvent(org.eclipse.scout.rt.platform.job.listener.JobEvent) Test(org.junit.Test) Times(org.eclipse.scout.rt.testing.platform.runner.Times)

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