use of org.eclipse.scout.rt.platform.job.IBlockingCondition in project scout.rt by eclipse.
the class ServerSessionCacheTest method testParallelRequestsWithdifferentIds.
@Test
public void testParallelRequestsWithdifferentIds() {
final TestHttpSession httpSession1 = new TestHttpSession();
final TestHttpSession httpSession2 = new TestHttpSession();
final ServerSessionCache cache = BEANS.get(ServerSessionCache.class);
final IBlockingCondition bc = Jobs.newBlockingCondition(true);
final IServerSessionLifecycleHandler handler1 = new TestServerSessionLifecycleHandler("id1") {
@Override
public IServerSession create() {
bc.waitFor(1, TimeUnit.SECONDS);
return super.create();
}
};
final IServerSessionLifecycleHandler handler2 = new TestServerSessionLifecycleHandler("id2") {
@Override
public IServerSession create() {
bc.setBlocking(false);
return super.create();
}
};
IFuture<IServerSession> f1 = Jobs.schedule(new Callable<IServerSession>() {
@Override
public IServerSession call() throws Exception {
return cache.getOrCreate(handler1, httpSession1);
}
}, Jobs.newInput());
IFuture<IServerSession> f2 = Jobs.schedule(new Callable<IServerSession>() {
@Override
public IServerSession call() throws Exception {
return cache.getOrCreate(handler2, httpSession2);
}
}, Jobs.newInput());
IServerSession session2 = f2.awaitDoneAndGet();
IServerSession session1 = f1.awaitDoneAndGet();
assertNotNull(session2);
assertNotNull(session1);
assertNotSame(session1, session2);
}
use of org.eclipse.scout.rt.platform.job.IBlockingCondition in project scout.rt by eclipse.
the class ClientHttpServiceTunnel method dispatchClientNotifications.
/**
* dispatch notifications in a client job and ensure to wait for dispatched notifications
*
* @param notifications
* the notifications to dispatch
*/
protected void dispatchClientNotifications(final List<ClientNotificationMessage> notifications) {
if (CollectionUtility.isEmpty(notifications)) {
return;
}
final IBlockingCondition cond = Jobs.newBlockingCondition(true);
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
ClientNotificationDispatcher notificationDispatcher = BEANS.get(ClientNotificationDispatcher.class);
notificationDispatcher.dispatchNotifications(notifications);
}
}, Jobs.newInput().withRunContext(ClientRunContexts.copyCurrent())).whenDone(new IDoneHandler<Void>() {
@Override
public void onDone(DoneEvent<Void> event) {
cond.setBlocking(false);
}
}, null);
cond.waitFor();
}
use of org.eclipse.scout.rt.platform.job.IBlockingCondition in project scout.rt by eclipse.
the class BlockingTestUtility method runBlockingAction.
/**
* Helper method to test code which will enter a blocking condition.
* <p>
* If <code>runnableOnceBlocked</code> throws an exception, it is given to {@link JUnitExceptionHandler} to make the
* JUnit test fail.
*
* @param runnableGettingBlocked
* {@code IRunnable} that will enter a blocking condition.
* @param runnableOnceBlocked
* {@code IRunnable} to be executed once the 'runnableGettingBlocked' enters a blocking condition.
* @param awaitBackgroundJobs
* true waits for background jobs running in the same session to complete before runnableOnceBlocked is
* called
*/
public static void runBlockingAction(final IRunnable runnableGettingBlocked, final IRunnable runnableOnceBlocked, final boolean awaitBackgroundJobs) {
final ClientRunContext runContext = ClientRunContexts.copyCurrent();
final IBlockingCondition onceBlockedDoneCondition = Jobs.newBlockingCondition(true);
// remember the list of client jobs before blocking
final Set<IFuture<?>> jobsBefore = new HashSet<>();
jobsBefore.addAll(BEANS.get(IJobManager.class).getFutures(new IFilter<IFuture<?>>() {
@Override
public boolean accept(IFuture<?> cand) {
final RunContext candContext = cand.getJobInput().getRunContext();
return candContext instanceof ClientRunContext && ((ClientRunContext) candContext).getSession() == runContext.getSession();
}
}));
final IRegistrationHandle listenerRegistration = IFuture.CURRENT.get().addListener(Jobs.newEventFilterBuilder().andMatchEventType(JobEventType.JOB_STATE_CHANGED).andMatchState(JobState.WAITING_FOR_BLOCKING_CONDITION).andMatchExecutionHint(ModelJobs.EXECUTION_HINT_UI_INTERACTION_REQUIRED).toFilter(), new IJobListener() {
@Override
public void changed(final JobEvent event) {
// waitFor was entered
final IRunnable callRunnableOnceBlocked = new IRunnable() {
@Override
public void run() throws Exception {
try {
runnableOnceBlocked.run();
} finally {
event.getData().getBlockingCondition().setBlocking(false);
onceBlockedDoneCondition.setBlocking(false);
}
}
};
final JobInput jobInputForRunnableOnceBlocked = ModelJobs.newInput(runContext).withExceptionHandling(BEANS.get(JUnitExceptionHandler.class), true).withName("JUnit: Handling blocked thread because waiting for a blocking condition");
if (awaitBackgroundJobs) {
// wait until all background jobs finished
Jobs.schedule(new IRunnable() {
@Override
public void run() throws Exception {
jobsBefore.add(IFuture.CURRENT.get());
BEANS.get(IJobManager.class).awaitFinished(new IFilter<IFuture<?>>() {
@Override
public boolean accept(IFuture<?> f) {
RunContext candContext = f.getJobInput().getRunContext();
return candContext instanceof ClientRunContext && ((ClientRunContext) candContext).getSession() == runContext.getSession() && !jobsBefore.contains(f);
}
}, 5, TimeUnit.MINUTES);
// call runnableOnceBlocked
ModelJobs.schedule(callRunnableOnceBlocked, jobInputForRunnableOnceBlocked);
}
}, Jobs.newInput().withName("wait until background jobs finished"));
} else {
// call runnableOnceBlocked directly
ModelJobs.schedule(callRunnableOnceBlocked, jobInputForRunnableOnceBlocked);
}
}
});
try {
// this action will enter a blocking condition which causes the 'runnableOnceBlocked' to be executed.
runnableGettingBlocked.run();
} catch (final Exception e) {
throw BEANS.get(DefaultRuntimeExceptionTranslator.class).translate(e);
} finally {
listenerRegistration.dispose();
}
// we need to wait until the runnableOnceBlocked is completed.
// runnableOnceBlocked may, during its execution, set the original blocking condition to non-blocking but still execute
// important code afterwards. Therefore, the original blocking condition that starts runnableOnceBlocked is only used
// to indicate the start of the runnableOnceBlocked, but this method returns only AFTER runnableOnceBlocked completes execution.
onceBlockedDoneCondition.waitForUninterruptibly(120, TimeUnit.SECONDS);
}
use of org.eclipse.scout.rt.platform.job.IBlockingCondition in project scout.rt by eclipse.
the class SmartFieldSingleResultTest method test.
@Test
public void test() throws Exception {
final IBlockingCondition bc = Jobs.newBlockingCondition(true);
m_smartField.getLookupRowFetcher().addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (IContentAssistFieldLookupRowFetcher.PROP_SEARCH_RESULT.equals(evt.getPropertyName())) {
bc.setBlocking(false);
}
}
});
m_smartField.getUIFacade().openProposalChooserFromUI("", true, false);
bc.waitFor();
// Without the bugfix the accepted proposal would be "SingleResult"
assertNull(m_smartField.getProposalChooser().getAcceptedProposal());
m_smartField.getUIFacade().acceptProposalFromUI("", false, false);
// Without the bugfix the current lookup-row would be "SingleResult"
assertFalse(m_smartField.isCurrentLookupRowSet());
}
use of org.eclipse.scout.rt.platform.job.IBlockingCondition 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;
}
}
Aggregations