Search in sources :

Example 76 with IRunnable

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

the class MutualExclusionTest method testBlockingCondition_InterruptedWhileReAcquiringTheMutex.

/**
 * We have 3 jobs that are scheduled simultaneously. Thereby, job1 enters a blocking condition which in turn lets job2
 * run. Job2 unblocks job1 so that job1 is trying to re-acquire the mutex. While waiting for the mutex to be
 * available, job1 is interrupted due to a cancel-request of job2.<br/>
 * This test verifies, that job1 is interrupted, competes for the mutex anew and only continues once a permit becomes
 * available. Also, job3 must not start running as long as job1 did not complete.
 */
@Test
// regression
@Times(100)
public void testBlockingCondition_InterruptedWhileReAcquiringTheMutex() throws java.lang.InterruptedException {
    // synchronized because modified/read by different threads.
    final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    final BlockingCountDownLatch latchJob2 = new BlockingCountDownLatch(1);
    final BlockingCountDownLatch job1FinishLatch = new BlockingCountDownLatch(1);
    final IFuture<Void> future1 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("running-1");
            try {
                protocol.add("before-blocking-1");
                condition.waitFor();
            } catch (ThreadInterruptedError e) {
                protocol.add("interrupted-1 (a)");
            } catch (RuntimeException e) {
                protocol.add("jobException-1");
            }
            if (Thread.currentThread().isInterrupted()) {
                protocol.add("interrupted-1 (b)");
            }
            if (ModelJobs.isModelThread()) {
                protocol.add("model-thread-1");
            }
            protocol.add("done-1");
            job1FinishLatch.countDown();
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    final IFuture<Void> future2 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("running-2a");
            if (future1.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("job2: job-1-waiting-for-blocking-condition");
            }
            if (!future1.getExecutionSemaphore().isPermitOwner(future1)) {
                protocol.add("job2: job-1-not-permit-owner");
            }
            protocol.add("unblocking condition");
            condition.setBlocking(false);
            // job-1 (interrupted acquisition task), job-2 (latch), job-3 (waiting for mutex)
            JobTestUtil.waitForPermitCompetitors(m_clientSession.getModelJobSemaphore(), 3);
            if (future1.getState() == JobState.WAITING_FOR_PERMIT) {
                protocol.add("job2: job-1-waiting-for-mutex");
            }
            protocol.add("before-cancel-job1-2");
            // interrupt job1 while acquiring the mutex
            future1.cancel(true);
            // job-1 (interrupted acquisition task), job-1 (re-acquiring a permit), job-2 (latch), job-3 (waiting for mutex)
            JobTestUtil.waitForPermitCompetitors(m_clientSession.getModelJobSemaphore(), 4);
            // cancelled, but still running
            JobTestUtil.waitForState(future1, JobState.DONE);
            protocol.add("running-2b");
            latchJob2.countDownAndBlock();
            protocol.add("done-2");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    final IFuture<Void> future3 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("done-3");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-3").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    assertTrue(latchJob2.await());
    assertEquals(future1.getState(), JobState.DONE);
    assertEquals(future2.getState(), JobState.RUNNING);
    assertEquals(future3.getState(), JobState.WAITING_FOR_PERMIT);
    latchJob2.unblock();
    Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter(), 5, TimeUnit.SECONDS);
    List<String> expectedProtocol = new ArrayList<>();
    expectedProtocol.add("running-1");
    expectedProtocol.add("before-blocking-1");
    expectedProtocol.add("running-2a");
    expectedProtocol.add("job2: job-1-waiting-for-blocking-condition");
    expectedProtocol.add("job2: job-1-not-permit-owner");
    expectedProtocol.add("unblocking condition");
    expectedProtocol.add("job2: job-1-waiting-for-mutex");
    expectedProtocol.add("before-cancel-job1-2");
    expectedProtocol.add("running-2b");
    expectedProtocol.add("done-2");
    expectedProtocol.add("interrupted-1 (b)");
    expectedProtocol.add("model-thread-1");
    expectedProtocol.add("done-1");
    expectedProtocol.add("done-3");
    assertEquals(expectedProtocol, protocol);
    assertEquals(future1.getState(), JobState.DONE);
    assertEquals(future2.getState(), JobState.DONE);
    assertEquals(future3.getState(), JobState.DONE);
    assertTrue(future1.isCancelled());
    future1.awaitDone(1, TimeUnit.NANOSECONDS);
    assertFalse(future2.isCancelled());
    future2.awaitDone(1, TimeUnit.NANOSECONDS);
    assertFalse(future3.isCancelled());
    future3.awaitDone(1, TimeUnit.NANOSECONDS);
}
Also used : BlockingCountDownLatch(org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch) ArrayList(java.util.ArrayList) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) ProcessingException(org.eclipse.scout.rt.platform.exception.ProcessingException) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) IBlockingCondition(org.eclipse.scout.rt.platform.job.IBlockingCondition) Test(org.junit.Test) Times(org.eclipse.scout.rt.testing.platform.runner.Times)

Example 77 with IRunnable

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

the class MutualExclusionTest method runTestBlockingConditionMultipleFlat.

private void runTestBlockingConditionMultipleFlat(final IBlockingCondition condition) {
    condition.setBlocking(true);
    // synchronized because modified/read by different threads.
    final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
    final IFuture<Void> future1 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-1-beforeAwait");
            condition.waitFor();
            protocol.add("job-X-afterAwait");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER).withName("job-1"));
    final IFuture<Void> future2 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-2-beforeAwait");
            condition.waitFor();
            protocol.add("job-X-afterAwait");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER).withName("job-2"));
    final IFuture<Void> future3 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-3-beforeAwait");
            condition.waitFor();
            protocol.add("job-X-afterAwait");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER).withName("job-3"));
    ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-4-running");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER).withName("job-4"));
    ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-5-running");
            if (future1.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("job-1-blocked");
            }
            if (future2.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("job-2-blocked");
            }
            if (future3.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("job-3-blocked");
            }
            protocol.add("job-5-signaling");
            condition.setBlocking(false);
            // Wait until the other jobs tried to re-acquire the mutex.
            JobTestUtil.waitForPermitCompetitors(m_clientSession.getModelJobSemaphore(), 4);
            if (future1.getState() == JobState.WAITING_FOR_PERMIT) {
                protocol.add("job-1-unblocked");
            }
            if (future2.getState() == JobState.WAITING_FOR_PERMIT) {
                protocol.add("job-2-unblocked");
            }
            if (future3.getState() == JobState.WAITING_FOR_PERMIT) {
                protocol.add("job-3-unblocked");
            }
            if (!future1.isDone()) {
                protocol.add("job-1-stillRunning");
            }
            if (!future2.isDone()) {
                protocol.add("job-2-stillRunning");
            }
            if (!future3.isDone()) {
                protocol.add("job-3-stillRunning");
            }
            protocol.add("job-5-ending");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withExecutionHint(JOB_IDENTIFIER).withName("job-5"));
    awaitDoneElseFail(JOB_IDENTIFIER);
    List<String> expected = new ArrayList<>();
    expected.add("job-1-beforeAwait");
    expected.add("job-2-beforeAwait");
    expected.add("job-3-beforeAwait");
    expected.add("job-4-running");
    expected.add("job-5-running");
    expected.add("job-1-blocked");
    expected.add("job-2-blocked");
    expected.add("job-3-blocked");
    expected.add("job-5-signaling");
    expected.add("job-1-unblocked");
    expected.add("job-2-unblocked");
    expected.add("job-3-unblocked");
    expected.add("job-1-stillRunning");
    expected.add("job-2-stillRunning");
    expected.add("job-3-stillRunning");
    expected.add("job-5-ending");
    // no guarantee about the sequence in which waiting threads are released when the blocking condition falls.
    expected.add("job-X-afterAwait");
    // no guarantee about the sequence in which waiting threads are released when the blocking condition falls.
    expected.add("job-X-afterAwait");
    // no guarantee about the sequence in which waiting threads are released when the blocking condition falls.
    expected.add("job-X-afterAwait");
    assertEquals(expected, protocol);
}
Also used : ArrayList(java.util.ArrayList) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) ProcessingException(org.eclipse.scout.rt.platform.exception.ProcessingException) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException)

Example 78 with IRunnable

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

the class MutualExclusionTest method testBlockingConditionSingle.

/**
 * Tests a BlockingCondition that blocks a single model-thread.
 */
@Test
public void testBlockingConditionSingle() {
    // synchronized because modified/read by different threads.
    final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    final IFuture<Void> future1 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("1: running");
            if (Jobs.getJobManager().isDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter())) {
                protocol.add("1: idle [a]");
            }
            if (IFuture.CURRENT.get().getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("1: blocked [a]");
            }
            if (ModelJobs.isModelThread()) {
                protocol.add("1: modelThread [a]");
            }
            protocol.add("1: beforeAwait");
            condition.waitFor();
            protocol.add("1: afterAwait");
            if (IFuture.CURRENT.get().getState() == JobState.RUNNING) {
                protocol.add("1: state=running");
            }
            if (Jobs.getJobManager().isDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter())) {
                protocol.add("1: idle [b]");
            }
            if (IFuture.CURRENT.get().getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("1: blocked [b]");
            }
            if (ModelJobs.isModelThread()) {
                protocol.add("1: modelThread [b]");
            }
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("2: running");
            if (Jobs.getJobManager().isDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter())) {
                protocol.add("2: idle [a]");
            }
            if (future1.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("2: job-1-state: waiting-for-condition");
            }
            if (IFuture.CURRENT.get().getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("2: blocked [a]");
            }
            if (ModelJobs.isModelThread()) {
                protocol.add("2: modelThread [a]");
            }
            // RELEASE THE BlockingCondition
            protocol.add("2: beforeSignaling");
            condition.setBlocking(false);
            protocol.add("2: afterSignaling");
            // Wait until job1 is competing for the mutex anew
            JobTestUtil.waitForPermitCompetitors(ClientRunContexts.copyCurrent().getSession().getModelJobSemaphore(), 2);
            if (future1.getState() == JobState.WAITING_FOR_PERMIT) {
                protocol.add("2: job-1-state: waiting-for-mutex");
            }
            if (Jobs.getJobManager().isDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter())) {
                protocol.add("2: idle [b]");
            }
            if (IFuture.CURRENT.get().getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("2: blocked [b]");
            }
            if (ModelJobs.isModelThread()) {
                protocol.add("2: modelThread [b]");
            }
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    // Wait until job1 completed.
    future1.awaitDoneAndGet(30, TimeUnit.SECONDS);
    awaitDoneElseFail(JOB_IDENTIFIER);
    List<String> expected = new ArrayList<>();
    expected.add("1: running");
    expected.add("1: modelThread [a]");
    expected.add("1: beforeAwait");
    expected.add("2: running");
    expected.add("2: job-1-state: waiting-for-condition");
    expected.add("2: modelThread [a]");
    expected.add("2: beforeSignaling");
    expected.add("2: afterSignaling");
    expected.add("2: job-1-state: waiting-for-mutex");
    expected.add("2: modelThread [b]");
    expected.add("1: afterAwait");
    expected.add("1: state=running");
    expected.add("1: modelThread [b]");
    assertEquals(expected, protocol);
}
Also used : ArrayList(java.util.ArrayList) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) 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)

Example 79 with IRunnable

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

the class ClusterSynchronizationService method onMessage.

@Override
public void onMessage(IMessage<IClusterNotificationMessage> message) {
    final IClusterNotificationMessage notificationMessage = message.getTransferObject();
    if (isEnabled()) {
        // Do not progress notifications sent by node itself
        String originNode = notificationMessage.getProperties().getOriginNode();
        if (m_nodeId.equals(originNode)) {
            return;
        }
        getStatusInfoInternal().updateReceiveStatus(notificationMessage);
        getStatusInfoInternal(notificationMessage.getNotification().getClass()).updateReceiveStatus(notificationMessage);
        ServerRunContext serverRunContext = ServerRunContexts.empty();
        serverRunContext.withSubject(m_subject);
        serverRunContext.withSession(BEANS.get(ServerSessionProviderWithCache.class).provide(serverRunContext.copy()));
        serverRunContext.run(new IRunnable() {

            @Override
            public void run() throws Exception {
                NotificationHandlerRegistry reg = BEANS.get(NotificationHandlerRegistry.class);
                reg.notifyNotificationHandlers(notificationMessage.getNotification());
            }
        });
    }
}
Also used : NotificationHandlerRegistry(org.eclipse.scout.rt.shared.notification.NotificationHandlerRegistry) ServerRunContext(org.eclipse.scout.rt.server.context.ServerRunContext) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable)

Example 80 with IRunnable

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

the class SessionStore method startHousekeeping.

/**
 * If the given client session is still active, schedule a job that checks whether it is still in use after some time
 * (see {@link SessionStoreHousekeepingDelayProperty}). If not, it will be stopped and removed from the store. If the
 * session is inactive from the beginning, it is just removed from the store.
 * <p>
 * <b>Important:</b>: This method must be called from within a lock!
 */
protected void startHousekeeping(final IClientSession clientSession) {
    // No client session, no house keeping necessary
    if (clientSession == null) {
        return;
    }
    // If client session is already inactive, simply update the maps, but take no further action.
    if (!clientSession.isActive()) {
        LOG.info("Session housekeeping: Removing inactive client session with ID {} from store", clientSession.getId());
        removeClientSession(clientSession);
        return;
    }
    // Check if client session is still used after a few moments
    LOG.debug("Session housekeeping: Schedule job for client session with ID {}", clientSession.getId());
    final IFuture<Void> future = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            doHousekeeping(clientSession);
        }
    }, Jobs.newInput().withName("Performing session housekeeping for client session with ID {}", clientSession.getId()).withExecutionTrigger(Jobs.newExecutionTrigger().withStartIn(CONFIG.getPropertyValue(SessionStoreHousekeepingDelayProperty.class), TimeUnit.SECONDS)));
    // Put the future in a list, so we can cancel it if the session is requested again
    m_housekeepingFutures.put(clientSession.getId(), future);
}
Also used : SessionStoreHousekeepingDelayProperty(org.eclipse.scout.rt.ui.html.UiHtmlConfigProperties.SessionStoreHousekeepingDelayProperty) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable)

Aggregations

IRunnable (org.eclipse.scout.rt.platform.util.concurrent.IRunnable)260 Test (org.junit.Test)210 AssertionException (org.eclipse.scout.rt.platform.util.Assertions.AssertionException)82 BlockingCountDownLatch (org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch)68 ProcessingException (org.eclipse.scout.rt.platform.exception.ProcessingException)40 ArrayList (java.util.ArrayList)36 PlatformException (org.eclipse.scout.rt.platform.exception.PlatformException)32 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)26 TimedOutError (org.eclipse.scout.rt.platform.util.concurrent.TimedOutError)21 IBlockingCondition (org.eclipse.scout.rt.platform.job.IBlockingCondition)20 IExecutionSemaphore (org.eclipse.scout.rt.platform.job.IExecutionSemaphore)20 ThreadInterruptedError (org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)20 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)19 JobEvent (org.eclipse.scout.rt.platform.job.listener.JobEvent)17 VetoException (org.eclipse.scout.rt.platform.exception.VetoException)13 Times (org.eclipse.scout.rt.testing.platform.runner.Times)12 AtomicReference (java.util.concurrent.atomic.AtomicReference)11 IFuture (org.eclipse.scout.rt.platform.job.IFuture)10 IJobManager (org.eclipse.scout.rt.platform.job.IJobManager)10 JMSException (javax.jms.JMSException)9