Search in sources :

Example 6 with IExecutionSemaphore

use of org.eclipse.scout.rt.platform.job.IExecutionSemaphore in project scout.rt by eclipse.

the class ExecutionSemaphoreTest method testThreePermitsAndBlocking.

/**
 * Tests execution semaphore with 3 permits and with a blocking condition involved.
 * <p>
 * In total, 7 jobs are scheduled. Thereby, job-1 and job-3 never finish, and job-2 enters a blocking condition.
 * <p>
 * This test tests, that because job-2 enters a blocking condition, job-4 starts running. Once job-4 completed, job-5
 * starts running. Then, job-5 unblocks the conditions, with lets job-2 to continue after job-5 finished. After job-2
 * finished, job-6, and then job-7 start running.
 * <p>
 */
@Test
// regression
@Times(500)
public void testThreePermitsAndBlocking() throws InterruptedException {
    final IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(3);
    // synchronized because modified/read by different threads.
    final Set<String> protocol = Collections.synchronizedSet(new HashSet<String>());
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    final BlockingCountDownLatch setupLatch = new BlockingCountDownLatch(3);
    final BlockingCountDownLatch finishLatch = new BlockingCountDownLatch(2);
    final BlockingCountDownLatch latchJob2 = new BlockingCountDownLatch(1);
    final BlockingCountDownLatch latchJob5 = new BlockingCountDownLatch(1);
    final BlockingCountDownLatch latchJob6 = new BlockingCountDownLatch(1);
    final BlockingCountDownLatch latchJob7 = new BlockingCountDownLatch(1);
    // job-1
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-1-running");
            setupLatch.countDownAndBlock();
            finishLatch.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-1").withExecutionSemaphore(semaphore));
    // job-2
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-2-running (a)");
            condition.waitFor(30, TimeUnit.SECONDS);
            protocol.add("job-2-running (b)");
            latchJob2.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-2").withExecutionSemaphore(semaphore));
    // job-3
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-3-running");
            setupLatch.countDownAndBlock();
            finishLatch.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-3").withExecutionSemaphore(semaphore));
    // job-4
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-4-running");
            setupLatch.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-4").withExecutionSemaphore(semaphore));
    // job-5
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-5-running");
            condition.setBlocking(false);
            // Wait until job-2 is competing for a permit anew.
            // Otherwise, job-6 might get the permit before job-2.
            // permit-owners: job-1, job-3, job-5, queue: job-2 (RE-ACQUIRE), job-6, job-7
            JobTestUtil.waitForPermitCompetitors(semaphore, 6);
            latchJob5.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-5").withExecutionSemaphore(semaphore));
    // job-6
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-6-running");
            latchJob6.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-6").withExecutionSemaphore(semaphore));
    // job-7
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-7-running");
            latchJob7.countDownAndBlock();
        }
    }, Jobs.newInput().withName("job-7").withExecutionSemaphore(semaphore));
    // verify
    assertTrue(setupLatch.await());
    assertEquals(CollectionUtility.hashSet("job-1-running", "job-2-running (a)", "job-3-running", "job-4-running"), protocol);
    protocol.clear();
    setupLatch.unblock();
    assertTrue(latchJob5.await());
    assertEquals(CollectionUtility.hashSet("job-5-running"), protocol);
    protocol.clear();
    latchJob5.unblock();
    try {
        assertTrue(latchJob2.await());
    } catch (AssertionError e) {
        System.out.println(protocol);
        throw e;
    }
    assertEquals(CollectionUtility.hashSet("job-2-running (b)"), protocol);
    protocol.clear();
    latchJob2.unblock();
    assertTrue(latchJob6.await());
    assertEquals(CollectionUtility.hashSet("job-6-running"), protocol);
    protocol.clear();
    latchJob6.unblock();
    assertTrue(latchJob7.await());
    assertEquals(CollectionUtility.hashSet("job-7-running"), protocol);
    latchJob7.unblock();
    finishLatch.unblock();
}
Also used : BlockingCountDownLatch(org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch) IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) IBlockingCondition(org.eclipse.scout.rt.platform.job.IBlockingCondition) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) Test(org.junit.Test) Times(org.eclipse.scout.rt.testing.platform.runner.Times)

Example 7 with IExecutionSemaphore

use of org.eclipse.scout.rt.platform.job.IExecutionSemaphore in project scout.rt by eclipse.

the class PermitAcquisitionOrderTest method testOrderWithinFixedDelayRepetitiveJob.

/**
 * Tests permit acquisition of repetitive job at fixed delay.
 */
@Test
public void testOrderWithinFixedDelayRepetitiveJob() {
    // regression
    int regressionCount = 100;
    // synchronized because modified/read by different threads.
    final List<Integer> protocol = Collections.synchronizedList(new ArrayList<Integer>());
    final String jobIdentifier = UUID.randomUUID().toString();
    final IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(1);
    final AtomicInteger counter = new AtomicInteger();
    // Schedule repetitive semaphore aware job
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            final int a = counter.incrementAndGet();
            final int b = counter.incrementAndGet();
            protocol.add(a);
            Jobs.schedule(new IRunnable() {

                @Override
                public void run() throws Exception {
                    protocol.add(b);
                }
            }, Jobs.newInput().withName("inner").withExecutionSemaphore(semaphore).withExecutionHint(jobIdentifier));
        }
    }, Jobs.newInput().withName("outer").withExecutionSemaphore(semaphore).withExecutionHint(jobIdentifier).withExecutionTrigger(Jobs.newExecutionTrigger().withSchedule(FixedDelayScheduleBuilder.repeatForTotalCount(regressionCount, 1, TimeUnit.MILLISECONDS))));
    Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(jobIdentifier).toFilter(), Long.MAX_VALUE, TimeUnit.SECONDS);
    List<Integer> expectedProtocol = new ArrayList<>();
    for (int i = 1; i <= regressionCount * 2; i++) {
        expectedProtocol.add(i);
    }
    assertEquals(expectedProtocol, protocol);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) Test(org.junit.Test)

Example 8 with IExecutionSemaphore

use of org.eclipse.scout.rt.platform.job.IExecutionSemaphore in project scout.rt by eclipse.

the class PermitAcquisitionOrderTest method testOrderWithinFixedRateRepetitiveJob.

/**
 * Tests that a repetitive semaphore aware job does not acquire the permit before the scheduled job of the last round.
 */
@Test
public void testOrderWithinFixedRateRepetitiveJob() {
    // regression
    int regressionCount = 100;
    // synchronized because modified/read by different threads.
    final List<Integer> protocol = Collections.synchronizedList(new ArrayList<Integer>());
    final String jobIdentifier = UUID.randomUUID().toString();
    final IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(1);
    final AtomicInteger counter = new AtomicInteger();
    // Schedule repetitive semaphore aware job
    Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            final int a = counter.incrementAndGet();
            final int b = counter.incrementAndGet();
            protocol.add(a);
            Jobs.schedule(new IRunnable() {

                @Override
                public void run() throws Exception {
                    protocol.add(b);
                }
            }, Jobs.newInput().withExecutionSemaphore(semaphore).withExecutionHint(jobIdentifier));
        }
    }, Jobs.newInput().withExecutionSemaphore(semaphore).withExecutionHint(jobIdentifier).withExecutionTrigger(Jobs.newExecutionTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(1).withRepeatCount(regressionCount))));
    Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(jobIdentifier).toFilter(), 10, TimeUnit.SECONDS);
    // However, it is likely that rounds were consolidated, so simply compare the ascending order.
    for (int i = 0; i < protocol.size(); i++) {
        int expectedOrder = i + 1;
        int actualOrder = protocol.get(i).intValue();
        if (expectedOrder != actualOrder) {
            fail("expected=" + expectedOrder + ", actual=" + actualOrder + ", actualProtocol=" + protocol);
        }
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) Test(org.junit.Test)

Example 9 with IExecutionSemaphore

use of org.eclipse.scout.rt.platform.job.IExecutionSemaphore in project scout.rt by eclipse.

the class PermitAcquisitionOrderTest method testOrderIfStartingInSequence.

/**
 * Tests that schedule aware jobs scheduled in a row respect the scheduling order when acquiring a permit.
 */
@Test
public void testOrderIfStartingInSequence() {
    // regression
    int regressionCount = 100;
    // synchronized because modified/read by different threads.
    final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
    final String jobIdentifier = UUID.randomUUID().toString();
    IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(1);
    // Schedule 100 jobs to start at the same time
    for (int i = 0; i < regressionCount; i++) {
        Jobs.schedule(new IRunnable() {

            @Override
            public void run() throws Exception {
                protocol.add(IFuture.CURRENT.get().getJobInput().getName());
            }
        }, Jobs.newInput().withName("job-{}", i).withExecutionSemaphore(semaphore).withExecutionHint(jobIdentifier));
    }
    Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(jobIdentifier).toFilter(), 10, TimeUnit.SECONDS);
    List<String> expectedProtocol = new ArrayList<>();
    for (int i = 0; i < regressionCount; i++) {
        expectedProtocol.add("job-" + i);
    }
    assertEquals(expectedProtocol, protocol);
}
Also used : ArrayList(java.util.ArrayList) IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) Test(org.junit.Test)

Example 10 with IExecutionSemaphore

use of org.eclipse.scout.rt.platform.job.IExecutionSemaphore in project scout.rt by eclipse.

the class JobEventFilterBuilderTest method test.

@Test
public void test() {
    IExecutionSemaphore mutex1 = Jobs.newExecutionSemaphore(1);
    IExecutionSemaphore mutex2 = Jobs.newExecutionSemaphore(1);
    IFuture<?> future1 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("A").withExecutionHint(JOB_IDENTIFIER));
    IFuture<?> future2 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("B").withRunContext(RunContexts.empty()).withExecutionSemaphore(mutex1).withExecutionHint(JOB_IDENTIFIER));
    IFuture<?> future3 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("C").withRunContext(new P_RunContext()).withExecutionSemaphore(mutex1).withExecutionHint(JOB_IDENTIFIER));
    IFuture<?> future4 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("D").withExecutionHint(JOB_IDENTIFIER).withExecutionTrigger(Jobs.newExecutionTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever())));
    IFuture<?> future5 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("E").withExecutionHint(JOB_IDENTIFIER).withExecutionTrigger(Jobs.newExecutionTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever())));
    IFuture<?> future6 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("E").withRunContext(new P_RunContext()).withExecutionHint(JOB_IDENTIFIER).withExecutionTrigger(Jobs.newExecutionTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever())));
    IFuture<?> future7 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("F").withExecutionSemaphore(mutex1).withExecutionHint(JOB_IDENTIFIER));
    IFuture<?> future8 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("G").withExecutionSemaphore(mutex1).withExecutionHint(JOB_IDENTIFIER));
    IFuture<?> future9 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("H").withExecutionSemaphore(mutex2));
    IFuture<?> future10 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("I").withRunContext(new P_RunContext()).withExecutionSemaphore(mutex1).withExecutionHint(JOB_IDENTIFIER));
    // with filtering for futures
    IFilter<JobEvent> filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).toFilter();
    assertTrue(filter.accept(newJobStateChangedEvent(future1)));
    assertTrue(filter.accept(newJobStateChangedEvent(future2)));
    assertTrue(filter.accept(newJobStateChangedEvent(future3)));
    assertTrue(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertTrue(filter.accept(newJobStateChangedEvent(future8)));
    assertTrue(filter.accept(newJobStateChangedEvent(future9)));
    assertTrue(filter.accept(newJobStateChangedEvent(future10)));
    // additionally with filtering for single executing jobs
    filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().toFilter();
    assertTrue(filter.accept(newJobStateChangedEvent(future1)));
    assertTrue(filter.accept(newJobStateChangedEvent(future2)));
    assertTrue(filter.accept(newJobStateChangedEvent(future3)));
    assertFalse(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertTrue(filter.accept(newJobStateChangedEvent(future8)));
    assertTrue(filter.accept(newJobStateChangedEvent(future9)));
    assertTrue(filter.accept(newJobStateChangedEvent(future10)));
    // additionally with filtering for mutex
    filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).toFilter();
    assertFalse(filter.accept(newJobStateChangedEvent(future1)));
    assertTrue(filter.accept(newJobStateChangedEvent(future2)));
    assertTrue(filter.accept(newJobStateChangedEvent(future3)));
    assertFalse(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertTrue(filter.accept(newJobStateChangedEvent(future8)));
    assertFalse(filter.accept(newJobStateChangedEvent(future9)));
    assertTrue(filter.accept(newJobStateChangedEvent(future10)));
    // additionally with filtering for jobs running on behalf of a RunContext
    filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(RunContext.class).toFilter();
    assertFalse(filter.accept(newJobStateChangedEvent(future1)));
    assertTrue(filter.accept(newJobStateChangedEvent(future2)));
    assertTrue(filter.accept(newJobStateChangedEvent(future3)));
    assertFalse(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertFalse(filter.accept(newJobStateChangedEvent(future8)));
    assertFalse(filter.accept(newJobStateChangedEvent(future9)));
    assertTrue(filter.accept(newJobStateChangedEvent(future10)));
    // additionally with filtering for jobs running on behalf of a specific P_RunContext
    filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(P_RunContext.class).toFilter();
    assertFalse(filter.accept(newJobStateChangedEvent(future1)));
    assertFalse(filter.accept(newJobStateChangedEvent(future2)));
    assertTrue(filter.accept(newJobStateChangedEvent(future3)));
    assertFalse(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertFalse(filter.accept(newJobStateChangedEvent(future8)));
    assertFalse(filter.accept(newJobStateChangedEvent(future9)));
    assertTrue(filter.accept(newJobStateChangedEvent(future10)));
    // additionally with filtering for names
    filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(P_RunContext.class).andMatchName("A", "B", "C").toFilter();
    assertFalse(filter.accept(newJobStateChangedEvent(future1)));
    assertFalse(filter.accept(newJobStateChangedEvent(future2)));
    assertTrue(filter.accept(newJobStateChangedEvent(future3)));
    assertFalse(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertFalse(filter.accept(newJobStateChangedEvent(future8)));
    assertFalse(filter.accept(newJobStateChangedEvent(future9)));
    assertFalse(filter.accept(newJobStateChangedEvent(future10)));
    // additionally with filtering for other names
    filter = new JobEventFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(P_RunContext.class).andMatchName("D", "E", "F").toFilter();
    assertFalse(filter.accept(newJobStateChangedEvent(future1)));
    assertFalse(filter.accept(newJobStateChangedEvent(future2)));
    assertFalse(filter.accept(newJobStateChangedEvent(future3)));
    assertFalse(filter.accept(newJobStateChangedEvent(future4)));
    assertFalse(filter.accept(newJobStateChangedEvent(future5)));
    assertFalse(filter.accept(newJobStateChangedEvent(future6)));
    assertFalse(filter.accept(newJobStateChangedEvent(future7)));
    assertFalse(filter.accept(newJobStateChangedEvent(future8)));
    assertFalse(filter.accept(newJobStateChangedEvent(future9)));
    assertFalse(filter.accept(newJobStateChangedEvent(future10)));
}
Also used : JobEvent(org.eclipse.scout.rt.platform.job.listener.JobEvent) IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) Test(org.junit.Test)

Aggregations

IExecutionSemaphore (org.eclipse.scout.rt.platform.job.IExecutionSemaphore)28 Test (org.junit.Test)26 IRunnable (org.eclipse.scout.rt.platform.util.concurrent.IRunnable)23 AssertionException (org.eclipse.scout.rt.platform.util.Assertions.AssertionException)11 BlockingCountDownLatch (org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch)8 IBlockingCondition (org.eclipse.scout.rt.platform.job.IBlockingCondition)6 IFuture (org.eclipse.scout.rt.platform.job.IFuture)5 Times (org.eclipse.scout.rt.testing.platform.runner.Times)5 TimedOutError (org.eclipse.scout.rt.platform.util.concurrent.TimedOutError)4 ArrayList (java.util.ArrayList)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 ProcessingException (org.eclipse.scout.rt.platform.exception.ProcessingException)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 JobEvent (org.eclipse.scout.rt.platform.job.listener.JobEvent)2 Date (java.util.Date)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 JMSException (javax.jms.JMSException)1 NamingException (javax.naming.NamingException)1 ClientRunContext (org.eclipse.scout.rt.client.context.ClientRunContext)1 PlatformException (org.eclipse.scout.rt.platform.exception.PlatformException)1