CompositeModuleInterpreterActor extends AbstractModuleInterpreterActor { private ActorRef getChildExecutor(RuntimeModule submodule) { assert state == State.REPLAY || state == State.RUNNING || state == State.ALL_OUTPUTS; int submoduleId = submodule.getIndex(); if (childExecutors[submoduleId] == null) { List<SubmoduleInPortNode> submoduleInPortNodes = dependencyGraph.submodulesInPortNodes().get(submoduleId); ImmutableList<HasValue> submoduleInPortHasValueList = submoduleInPortNodes.stream() .map(SubmoduleInPortNode::getHasValue) .collect(ImmutableList.collector()); BitSet submoduleRecomputedInPorts = new BitSet(submodule.getInPorts().size()); submoduleInPortNodes.stream() .filter(node -> node.getPortState() == PortState.RECOMPUTE) .forEach(node -> submoduleRecomputedInPorts.set(node.getElement().getInIndex())); BitSet submoduleRequestedOutPorts = computeResumeState.getSubmodulesNeededOutPorts()[submoduleId]; submoduleRequestedOutPorts.stream() .mapToObj(id -> submodule.getOutPorts().get(id)) .forEach( outPort -> startAsynchronousAction( outPort, "waiting for value to pass through submodule out-port %s#%s", submodule.getSimpleName(), outPort.getSimpleName() ) ); childExecutors[submoduleId] = getContext().actorOf( interpreterPropsProvider.provideInterpreterProps( getInterpreterProperties(), stagingArea.resolveDescendant( ExecutionTrace.empty().resolveContent().resolveModule(submodule.getSimpleName()) ), submoduleId, submoduleInPortHasValueList, submoduleRecomputedInPorts, submoduleRequestedOutPorts ), submodule.getSimpleName().toString() ); getContext().watch(childExecutors[submoduleId]); childActorMap.put(childExecutors[submoduleId], submodule); startAsynchronousAction(childExecutors[submoduleId], "supervising interpreter for submodule %s", submodule.getSimpleName()); } return childExecutors[submoduleId]; } private  CompositeModuleInterpreterActor(Factory factory); @Override void preStart(); @Override void postStop(); @Override void onReceive(Object message);  }
@Test public void lifecycleEvents() { try (ModuleInterpretation moduleInterpretation = testCaseBuilder("lifecycleEvents", INLINE_CONTEXT).build()) { Props props = moduleInterpretation.toCompositeModuleInterpreterProps(3, bitSetOf(), bitSetOf(2)); long timestampLowerBound = System.currentTimeMillis(); TestActorRef<CompositeModuleInterpreterActor> actorRef = TestActorRef.create(moduleInterpretation.getActorSystem(), props); TestProbe eventProbe = moduleInterpretation.getEventProbe(); BeginExecutionTraceEvent beginExecutionTraceEvent = eventProbe.expectMsgClass(BeginExecutionTraceEvent.class); LocalInterpreterProperties localInterpreterProperties = moduleInterpretation.getLocalInterpreterProperties(); Assert.assertEquals( beginExecutionTraceEvent, BeginExecutionTraceEvent.of( localInterpreterProperties.getExecutionId(), beginExecutionTraceEvent.getTimestamp(), moduleInterpretation.getStagingArea().getAnnotatedExecutionTrace() ) ); Assert.assertTrue(timestampLowerBound <= beginExecutionTraceEvent.getTimestamp() && beginExecutionTraceEvent.getTimestamp() <= System.currentTimeMillis()); Assert.assertFalse(eventProbe.msgAvailable()); CompositeModuleInterpreterActor actor = actorRef.underlyingActor(); int dId = submodule(moduleInterpretation, "d").getIndex(); Assert.assertNull(actor.getChildExecutor(dId)); moduleInterpretation.getAsyncTaskExecutor().executeAll(); Assert.assertNotNull(actor.getChildExecutor(dId)); actorRef.stop(); EndExecutionTraceEvent endExecutionTraceEvent = eventProbe.expectMsgClass(EndExecutionTraceEvent.class); Assert.assertEquals( endExecutionTraceEvent, EndExecutionTraceEvent.of( localInterpreterProperties.getExecutionId(), endExecutionTraceEvent.getTimestamp(), moduleInterpretation.getStagingArea().getAnnotatedExecutionTrace(), false ) ); Assert.assertTrue(beginExecutionTraceEvent.getTimestamp() <= endExecutionTraceEvent.getTimestamp() && endExecutionTraceEvent.getTimestamp() <= System.currentTimeMillis()); Assert.assertFalse(eventProbe.msgAvailable()); } }