@Test(timeout = 30000) public void testAsyncWorkItem() throws Exception { ExecutorService executorService = ExecutorServiceFactory.newExecutorService(); executorService.setThreadPoolSize(1); executorService.setInterval(1); executorService.setRetries(2); executorService.init(); addWorkItemHandler("async", new AsyncWorkItemHandler(executorService)); addWorkItemHandler("Milestone", new SystemOutWorkItemHandler()); KieSession ksession = createKSession(TERMINATE_CASE); RuntimeEngine runtimeEngine = getRuntimeEngine(); CaseMgmtService caseMgmtService = new CaseMgmtUtil(runtimeEngine); ProcessInstance pi = caseMgmtService.startNewCase("AsyncWorkItem"); long pid = pi.getId(); Map<String, Object> params = new HashMap<String, Object>(); params.put("CommandClass", CheckCallCommand.class.getCanonicalName()); caseMgmtService.createDynamicWorkTask(pid, "async", params); // This will time out if the barrier waits for longer than 5 seconds. // The .await(..) call will only timeout (throw an exception) if the // other party (that is calling .execute(CommandContext)) has *not* also // called await (in CheckCallCommand.execute(CommandContext) // In this way, it's also a check to see if the command has executed CheckCallCommand.getBarrier().await(5, TimeUnit.SECONDS); caseMgmtService.triggerAdHocFragment(pid, "Terminate"); }
public void signalEvent(String type, Object event) { String actualSignalType = type.replaceFirst(ASYNC_SIGNAL_PREFIX, ""); ProcessPersistenceContextManager contextManager = (ProcessPersistenceContextManager) getKnowledgeRuntime().getEnvironment().get(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER); ProcessPersistenceContext context = contextManager.getProcessPersistenceContext(); List<Long> processInstancesToSignalList = context.getProcessInstancesWaitingForEvent(actualSignalType); // handle signal asynchronously if (type.startsWith(ASYNC_SIGNAL_PREFIX)) { RuntimeManager runtimeManager = ((RuntimeManager) getKnowledgeRuntime().getEnvironment().get("RuntimeManager")); ExecutorService executorService = (ExecutorService) getKnowledgeRuntime().getEnvironment().get("ExecutorService"); if (runtimeManager != null && executorService != null) { for (Long processInstanceId : processInstancesToSignalList) { CommandContext ctx = new CommandContext(); ctx.setData("DeploymentId", runtimeManager.getIdentifier()); ctx.setData("ProcessInstanceId", processInstanceId); ctx.setData("Signal", actualSignalType); ctx.setData("Event", event); executorService.scheduleRequest(AsyncSignalEventCommand.class.getName(), ctx); } return; } else { logger.warn( "Signal should be sent asynchronously but there is no executor service available, continuing sync..."); } } for (long id : processInstancesToSignalList) { try { getKnowledgeRuntime().getProcessInstance(id); } catch (IllegalStateException e) { // IllegalStateException can be thrown when using RuntimeManager // and invalid ksession was used for given context } catch (RuntimeException e) { logger.warn( "Exception when loading process instance for signal '{}', instance with id {} will not be signaled", e.getMessage(), id); } } super.signalEvent(actualSignalType, event); }