diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/component/Component.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/component/Component.java index cbc489c4e69..d99afc43e64 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/component/Component.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/component/Component.java @@ -354,7 +354,12 @@ public ComponentState transition(Component component, LOG.info("[INIT COMPONENT " + component.getName() + "]: " + event .getDesired() + " instances."); component.requestContainers(component.pendingInstances.size()); - return checkIfStable(component); + ComponentState componentState = checkIfStable(component); + if (componentState == ComponentState.STABLE) { + component.context.getServiceManager().checkAndUpdateServiceState(); + } + return componentState; + } long before = component.getComponentSpec().getNumberOfContainers(); long delta = event.getDesired() - before; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestYarnNativeServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestYarnNativeServices.java index 4ede8cfbb93..d664669b6db 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestYarnNativeServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestYarnNativeServices.java @@ -202,6 +202,45 @@ public void testComponentStartOrder() throws Exception { client.actionDestroy(exampleApp.getName()); } + // Create compa with 1 containers + // Create compb with 1 containers which depends on compa + // Create compc with 0 containers which depends on compb + // Check containers for compa started before containers for compb before + // containers for compc + // After all, service state must be STABLE + @Test (timeout = 200000) + public void testComponentStartOrderWithNoInstanceComponent() throws Exception { + setupInternal(NUM_NMS); + ServiceClient client = createClient(getConf()); + Service exampleApp = new Service(); + exampleApp.setName("teststartorder-with-no-instance"); + exampleApp.setVersion("v1"); + exampleApp.addComponent(createComponent("compa", 1, "sleep 1000")); + + // Let compb depend on compa + Component compb = createComponent("compb", 1, "sleep 1000"); + compb.setDependencies(Collections.singletonList("compa")); + exampleApp.addComponent(compb); + + // Let compc depend on compb + Component compc = createComponent("compc", 0, "sleep 1000"); + compc.setDependencies(Collections.singletonList("compb")); + exampleApp.addComponent(compc); + + client.actionCreate(exampleApp); + waitForServiceToBeStable(client, exampleApp); + + // check that containers for compa are launched before containers for compb + checkContainerLaunchDependencies(client, exampleApp, "compa", "compb", + "compc"); + + Assert.assertEquals(ServiceState.STABLE, client.getStatus( + exampleApp.getName()).getState()); + + client.actionStop(exampleApp.getName(), true); + client.actionDestroy(exampleApp.getName()); + } + @Test(timeout = 200000) public void testCreateServiceSameNameDifferentUser() throws Exception { String sameAppName = "same-name";