Search in sources :

Example 6 with IFuture

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

the class AbstractClientSession method cancelRunningJobs.

protected void cancelRunningJobs() {
    // Filter matches all running jobs that have the same client session associated, except the current thread
    // and model jobs. Because the current thread is (or should be) a model job, we cannot wait for other
    // model threads. They are always cancelled.
    IFilter<IFuture<?>> runningJobsFilter = Jobs.newFutureFilterBuilder().andMatch(new SessionFutureFilter(ISession.CURRENT.get())).andMatchNotFuture(IFuture.CURRENT.get()).andMatchNot(ModelJobFutureFilter.INSTANCE).andMatchNotState(JobState.DONE, JobState.REJECTED).toFilter();
    // Wait for running jobs to complete before we cancel them
    long delay = NumberUtility.nvl(CONFIG.getPropertyValue(JobCompletionDelayOnSessionShutdown.class), 0L);
    if (delay > 0L) {
        try {
            Jobs.getJobManager().awaitDone(runningJobsFilter, delay, TimeUnit.SECONDS);
        } catch (TimedOutError e) {
        // NOSONAR
        // NOP (not all jobs have been finished within the delay)
        } catch (ThreadInterruptedError e) {
            LOG.warn("Failed to await for running jobs to complete.", e);
        }
    }
    // Cancel remaining jobs and write a warning to the logger
    Set<IFuture<?>> runningFutures = Jobs.getJobManager().getFutures(runningJobsFilter);
    if (!runningFutures.isEmpty()) {
        LOG.warn("Some running client jobs found while stopping the client session; sent a cancellation request to release associated worker threads. [session={}, user={}, jobs={}]", AbstractClientSession.this, getUserId(), runningFutures);
        Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder().andMatchFuture(runningFutures).toFilter(), true);
    }
    // Now cancel all other model jobs. Because the current thread is a model job, they can never run anyway.
    Set<IFuture<?>> runningModelJobs = Jobs.getJobManager().getFutures(Jobs.newFutureFilterBuilder().andMatch(new SessionFutureFilter(ISession.CURRENT.get())).andMatchNotFuture(IFuture.CURRENT.get()).andMatch(ModelJobFutureFilter.INSTANCE).andMatchNotState(JobState.DONE, JobState.REJECTED).toFilter());
    if (!runningModelJobs.isEmpty()) {
        LOG.info("Cancel running model jobs because the client session was shut down. [session={}, user={}, jobs={}]", AbstractClientSession.this, getUserId(), runningModelJobs);
        Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder().andMatchFuture(runningModelJobs).toFilter(), true);
    }
}
Also used : SessionFutureFilter(org.eclipse.scout.rt.shared.job.filter.future.SessionFutureFilter) JobCompletionDelayOnSessionShutdown(org.eclipse.scout.rt.client.ClientConfigProperties.JobCompletionDelayOnSessionShutdown) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) TimedOutError(org.eclipse.scout.rt.platform.util.concurrent.TimedOutError) IFuture(org.eclipse.scout.rt.platform.job.IFuture)

Example 7 with IFuture

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

the class ExecutionSemaphoreTest method testChangePermits1.

/**
 * Tests no permit available upon completion
 */
@Test
public void testChangePermits1() {
    final IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(1);
    // synchronized because modified/read by different threads.
    final Set<String> protocol = Collections.synchronizedSet(new HashSet<String>());
    final String executionHint = UUID.randomUUID().toString();
    IFuture<Void> future = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("job-1-running");
            Jobs.schedule(new IRunnable() {

                @Override
                public void run() throws Exception {
                    protocol.add("job-2-running");
                }
            }, Jobs.newInput().withName("job-2").withExecutionHint(executionHint).withExceptionHandling(null, false).withExecutionSemaphore(semaphore));
            // Change the permits to 0
            semaphore.withPermits(0);
        }
    }, Jobs.newInput().withName("job-1").withExecutionHint(executionHint).withExecutionSemaphore(semaphore));
    future.awaitDone(1, TimeUnit.SECONDS);
    assertEquals(CollectionUtility.hashSet("job-1-running"), protocol);
    IFilter<IFuture<?>> job2Filter = Jobs.newFutureFilterBuilder().andMatchExecutionHint(executionHint).toFilter();
    try {
        Jobs.getJobManager().awaitDone(job2Filter, 1, TimeUnit.SECONDS);
        fail("timeout expected because no permit available");
    } catch (TimedOutError e) {
    // NOOP
    }
    // Change permits to 1 --> job-2 should run
    protocol.clear();
    semaphore.withPermits(1);
    Jobs.getJobManager().awaitDone(job2Filter, 1, TimeUnit.SECONDS);
    assertEquals(CollectionUtility.hashSet("job-2-running"), protocol);
}
Also used : 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) IFuture(org.eclipse.scout.rt.platform.job.IFuture) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) Test(org.junit.Test)

Example 8 with IFuture

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

the class ExecutionSemaphoreTest method testInternalDeadlock.

/**
 * Tests an internal of {@link ExecutionSemaphore}, that {@link AcquisitionTask#notifyPermitAcquired()} is invoked
 * outside the {@link ExecutionSemaphore} lock.
 * <p>
 * Otherwise, a deadlock might occur, once the resuming job-1 tries to re-acquire the permit, namely exactly the time
 * when owning acquisitionLock in {@link ExecutionSemaphore#acquire(IFuture, QueuePosition)} and querying
 * 'isPermitOwner'. Thereto, job-1 must compete for the semaphore lock, while job-2 (owning semaphore lock) tries to
 * notify the resuming job-1 via {@link AcquisitionTask#notifyPermitAcquired()}, but cannot get monitor of
 * acquisitionLock.
 */
@Test
// regression; do not remove
@Times(1_000)
public void testInternalDeadlock() {
    final IExecutionSemaphore semaphore = Jobs.newExecutionSemaphore(1);
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    final AtomicReference<IFuture<?>> future2Ref = new AtomicReference<>();
    IFuture<Void> future1 = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            future2Ref.set(Jobs.schedule(new IRunnable() {

                @Override
                public void run() throws Exception {
                    condition.setBlocking(false);
                }
            }, Jobs.newInput().withName("job-2").withExecutionSemaphore(semaphore)));
            condition.waitFor();
        }
    }, Jobs.newInput().withName("job-1").withExecutionSemaphore(semaphore));
    try {
        future1.awaitDoneAndGet(5, TimeUnit.SECONDS);
    } catch (TimedOutError e) {
        fail(String.format("Deadlock while passing permit from 'job-2' to 'job-1' [job-1-state=%s, job-2-state=%s", future1.getState(), future2Ref.get().getState()));
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) 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) IFuture(org.eclipse.scout.rt.platform.job.IFuture) 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 9 with IFuture

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

the class FutureFilterBuilderTest 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).withExecutionHint(JOB_IDENTIFIER));
    IFuture<?> future10 = Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withName("I").withRunContext(new P_RunContext()).withExecutionSemaphore(mutex1).withExecutionHint(JOB_IDENTIFIER));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future1));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future2));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future3));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future4));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future5));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future6));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future7));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future8));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future9));
    assertTrue(new FutureFilterBuilder().toFilter().accept(future10));
    // with filtering for futures
    IFilter<IFuture<?>> filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).toFilter();
    assertTrue(filter.accept(future1));
    assertTrue(filter.accept(future2));
    assertTrue(filter.accept(future3));
    assertTrue(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertTrue(filter.accept(future8));
    assertTrue(filter.accept(future9));
    assertTrue(filter.accept(future10));
    // additionally with filtering for single executing jobs
    filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().toFilter();
    assertTrue(filter.accept(future1));
    assertTrue(filter.accept(future2));
    assertTrue(filter.accept(future3));
    assertFalse(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertTrue(filter.accept(future8));
    assertTrue(filter.accept(future9));
    assertTrue(filter.accept(future10));
    // additionally with filtering for mutex
    filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).toFilter();
    assertFalse(filter.accept(future1));
    assertTrue(filter.accept(future2));
    assertTrue(filter.accept(future3));
    assertFalse(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertTrue(filter.accept(future8));
    assertFalse(filter.accept(future9));
    assertTrue(filter.accept(future10));
    // additionally with filtering for jobs running on behalf of a RunContext
    filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(RunContext.class).toFilter();
    assertFalse(filter.accept(future1));
    assertTrue(filter.accept(future2));
    assertTrue(filter.accept(future3));
    assertFalse(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertFalse(filter.accept(future8));
    assertFalse(filter.accept(future9));
    assertTrue(filter.accept(future10));
    // additionally with filtering for jobs running on behalf of a specific P_RunContext
    filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(P_RunContext.class).toFilter();
    assertFalse(filter.accept(future1));
    assertFalse(filter.accept(future2));
    assertTrue(filter.accept(future3));
    assertFalse(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertFalse(filter.accept(future8));
    assertFalse(filter.accept(future9));
    assertTrue(filter.accept(future10));
    // additionally with filtering for names
    filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(P_RunContext.class).andMatchName("A", "B", "C").toFilter();
    assertFalse(filter.accept(future1));
    assertFalse(filter.accept(future2));
    assertTrue(filter.accept(future3));
    assertFalse(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertFalse(filter.accept(future8));
    assertFalse(filter.accept(future9));
    assertFalse(filter.accept(future10));
    // additionally with filtering for other names
    filter = new FutureFilterBuilder().andMatchFuture(future1, future2, future3, future4, future8, future9, future10).andAreSingleExecuting().andMatchExecutionSemaphore(mutex1).andMatchRunContext(P_RunContext.class).andMatchName("D", "E", "F").toFilter();
    assertFalse(filter.accept(future1));
    assertFalse(filter.accept(future2));
    assertFalse(filter.accept(future3));
    assertFalse(filter.accept(future4));
    assertFalse(filter.accept(future5));
    assertFalse(filter.accept(future6));
    assertFalse(filter.accept(future7));
    assertFalse(filter.accept(future8));
    assertFalse(filter.accept(future9));
    assertFalse(filter.accept(future10));
}
Also used : IExecutionSemaphore(org.eclipse.scout.rt.platform.job.IExecutionSemaphore) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) IFuture(org.eclipse.scout.rt.platform.job.IFuture) Test(org.junit.Test)

Example 10 with IFuture

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

the class AssertNoRunningJobsStatement method evaluate.

@Override
public void evaluate() throws Throwable {
    final ScheduledDescendantJobListener jobListener = new ScheduledDescendantJobListener();
    final IRegistrationHandle listenerRegistration = Jobs.getJobManager().addListener(Jobs.newEventFilterBuilder().andMatchEventType(JobEventType.JOB_STATE_CHANGED).andMatchState(JobState.SCHEDULED).toFilter(), jobListener);
    try {
        // Continue the chain.
        m_next.evaluate();
    } finally {
        listenerRegistration.dispose();
    }
    final Set<IFuture<?>> scheduledFutures = jobListener.getScheduledFutures();
    if (!scheduledFutures.isEmpty()) {
        assertNoRunningJobs(Jobs.newFutureFilterBuilder().andMatchFuture(scheduledFutures).toFilter());
    }
}
Also used : IRegistrationHandle(org.eclipse.scout.rt.platform.util.IRegistrationHandle) IFuture(org.eclipse.scout.rt.platform.job.IFuture)

Aggregations

IFuture (org.eclipse.scout.rt.platform.job.IFuture)19 IRunnable (org.eclipse.scout.rt.platform.util.concurrent.IRunnable)14 Test (org.junit.Test)12 AssertionException (org.eclipse.scout.rt.platform.util.Assertions.AssertionException)6 TimedOutError (org.eclipse.scout.rt.platform.util.concurrent.TimedOutError)6 IExecutionSemaphore (org.eclipse.scout.rt.platform.job.IExecutionSemaphore)5 ArrayList (java.util.ArrayList)4 ProcessingException (org.eclipse.scout.rt.platform.exception.ProcessingException)4 IBlockingCondition (org.eclipse.scout.rt.platform.job.IBlockingCondition)4 IClientSession (org.eclipse.scout.rt.client.IClientSession)3 IJobManager (org.eclipse.scout.rt.platform.job.IJobManager)3 HashSet (java.util.HashSet)2 ExecutorService (java.util.concurrent.ExecutorService)2 Future (java.util.concurrent.Future)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 JobInput (org.eclipse.scout.rt.platform.job.JobInput)2 JobFutureTask (org.eclipse.scout.rt.platform.job.internal.JobFutureTask)2 JobEvent (org.eclipse.scout.rt.platform.job.listener.JobEvent)2 IRegistrationHandle (org.eclipse.scout.rt.platform.util.IRegistrationHandle)2 ThreadInterruptedError (org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)2