SLIDER-202 Monkey implemented but not conditional/integrated
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/b111268a Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/b111268a Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/b111268a Branch: refs/heads/develop Commit: b111268af07a75797c9f56b3ab96c0dd052a62a8 Parents: c951e25 Author: Steve Loughran <ste...@apache.org> Authored: Wed Aug 13 12:00:27 2014 +0100 Committer: Steve Loughran <ste...@apache.org> Committed: Wed Aug 13 12:00:27 2014 +0100 ---------------------------------------------------------------------- .../server/appmaster/SliderAppMaster.java | 52 +++++++++++---- .../server/appmaster/actions/ActionHalt.java | 4 +- .../appmaster/actions/ActionKillContainer.java | 51 +++++++++++++++ .../server/appmaster/monkey/ChaosEntry.java | 53 ++++++++++++++- .../server/appmaster/monkey/ChaosKillAM.java | 48 ++++++++++++++ .../appmaster/monkey/ChaosKillContainer.java | 68 ++++++++++++++++++++ .../appmaster/monkey/ChaosMonkeyService.java | 41 ++++++++---- .../appmaster/monkey/MonkeyPlayAction.java | 48 ++++++++++++++ .../slider/server/appmaster/state/AppState.java | 14 +++- .../standalone/TestStandaloneAgentAM.groovy | 2 +- 10 files changed, 346 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java index 1135a58..ee0e59e 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java @@ -97,6 +97,7 @@ import org.apache.slider.providers.ProviderService; import org.apache.slider.providers.SliderProviderFactory; import org.apache.slider.providers.slideram.SliderAMClientProvider; import org.apache.slider.providers.slideram.SliderAMProviderService; +import org.apache.slider.server.appmaster.actions.ActionKillContainer; import org.apache.slider.server.appmaster.actions.QueueExecutor; import org.apache.slider.server.appmaster.actions.ActionHalt; import org.apache.slider.server.appmaster.actions.QueueService; @@ -104,6 +105,9 @@ import org.apache.slider.server.appmaster.actions.ActionStopSlider; import org.apache.slider.server.appmaster.actions.AsyncAction; import org.apache.slider.server.appmaster.actions.RenewingAction; import org.apache.slider.server.appmaster.actions.ResetFailureWindow; +import org.apache.slider.server.appmaster.monkey.ChaosKillAM; +import org.apache.slider.server.appmaster.monkey.ChaosKillContainer; +import org.apache.slider.server.appmaster.monkey.ChaosMonkeyService; import org.apache.slider.server.appmaster.operations.AsyncRMOperationHandler; import org.apache.slider.server.appmaster.operations.ProviderNotifyingOperationHandler; import org.apache.slider.server.appmaster.rpc.RpcBinder; @@ -112,7 +116,6 @@ import org.apache.slider.server.appmaster.rpc.SliderClusterProtocolPBImpl; import org.apache.slider.server.appmaster.operations.AbstractRMOperation; import org.apache.slider.server.appmaster.state.AppState; import org.apache.slider.server.appmaster.state.ContainerAssignment; -import org.apache.slider.server.appmaster.operations.ContainerReleaseOperation; import org.apache.slider.server.appmaster.state.ProviderAppState; import org.apache.slider.server.appmaster.operations.RMOperationHandler; import org.apache.slider.server.appmaster.state.RoleInstance; @@ -147,7 +150,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; @@ -301,6 +303,11 @@ public class SliderAppMaster extends AbstractSliderLaunchedService private ContainerId appMasterContainerID; /** + * Monkey Service -may be null + */ + private ChaosMonkeyService monkey; + + /** * ProviderService of this cluster */ @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") @@ -780,6 +787,8 @@ public class SliderAppMaster extends AbstractSliderLaunchedService // starts the node review process launchProviderService(instanceDefinition, confDir); + // chaos monkey + maybeStartMonkey(); try { //now block waiting to be told to exit the process @@ -1103,7 +1112,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService } //for all the operations, exec them - rmOperationHandler.execute(operations); + executeRMOperations(operations); log.info("Diagnostics: " + getContainerDiagnosticInfo()); } @@ -1221,7 +1230,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService // tell the provider providerRMOperationHandler.execute(allOperations); //now apply the operations - rmOperationHandler.execute(allOperations); + executeRMOperations(allOperations); return !allOperations.isEmpty(); } catch (TriggerClusterTeardownException e) { @@ -1237,7 +1246,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService */ private void releaseAllContainers() { //now apply the operations - rmOperationHandler.execute(appState.releaseAllContainers()); + executeRMOperations(appState.releaseAllContainers()); } /** @@ -1441,19 +1450,17 @@ public class SliderAppMaster extends AbstractSliderLaunchedService //throws NoSuchNodeException if it is missing RoleInstance instance = appState.getLiveInstanceByContainerID(containerID); - List<AbstractRMOperation> opsList = - new LinkedList<>(); - ContainerReleaseOperation release = - new ContainerReleaseOperation(instance.getId()); - opsList.add(release); - //now apply the operations - rmOperationHandler.execute(opsList); + queue(new ActionKillContainer(instance.getId(), 0, TimeUnit.MILLISECONDS)); Messages.KillContainerResponseProto.Builder builder = Messages.KillContainerResponseProto.newBuilder(); builder.setSuccess(true); return builder.build(); } + public void executeRMOperations(List<AbstractRMOperation> operations) { + rmOperationHandler.execute(operations); + } + @Override public Messages.AMSuicideResponseProto amSuicide( Messages.AMSuicideRequestProto request) @@ -1462,7 +1469,8 @@ public class SliderAppMaster extends AbstractSliderLaunchedService String text = request.getText(); int delay = request.getDelay(); log.info("AM Suicide with signal {}, message {} delay = {}", signal, text, delay); - ActionHalt action = new ActionHalt(signal, text, delay); + ActionHalt action = new ActionHalt(signal, text, delay, + TimeUnit.MILLISECONDS); schedule(action); return Messages.AMSuicideResponseProto.getDefaultInstance(); } @@ -1537,7 +1545,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService containerId); RoleInstance activeContainer = appState.getActiveContainer(containerId); if (activeContainer != null) { - rmOperationHandler.execute(appState.releaseContainer(containerId)); + executeRMOperations(appState.releaseContainer(containerId)); // ask for more containers if needed log.info("Container released; triggering review"); reviewRequestAndReleaseNodes(); @@ -1725,6 +1733,22 @@ public class SliderAppMaster extends AbstractSliderLaunchedService signalAMComplete(exitCode, exception.toString()); } + public boolean maybeStartMonkey() { + monkey = new ChaosMonkeyService(metrics, actionQueues); + int amKillProbability = 100; + int containerKillProbability = 200; + monkey.addTarget("AM killer", + new ChaosKillAM(this, actionQueues, -1), + amKillProbability); + monkey.addTarget("Container killer", + new ChaosKillContainer(this, actionQueues), + amKillProbability); + initAndAddService(monkey); + // and schedule it + schedule(monkey.getChaosAction(60, TimeUnit.SECONDS)); + return true; + } + /** * This is the main entry point for the service launcher. * @param args command line arguments. http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionHalt.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionHalt.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionHalt.java index b46a791..c21e249 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionHalt.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionHalt.java @@ -22,6 +22,8 @@ import org.apache.hadoop.util.ExitUtil; import org.apache.slider.server.appmaster.SliderAppMaster; import org.apache.slider.server.appmaster.state.AppState; +import java.util.concurrent.TimeUnit; + /** * Exit a JVM halt. * @see ExitUtil#halt(int, String) @@ -34,7 +36,7 @@ public class ActionHalt extends AsyncAction { public ActionHalt( int status, String text, - long delay) { + long delay, TimeUnit timeUnit) { super("Halt", delay, ActionAttributes.HALTS_CLUSTER); this.status = status; this.text = text; http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java new file mode 100644 index 0000000..7668bd5 --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.slider.server.appmaster.actions; + +import org.apache.hadoop.yarn.api.records.ContainerId; +import org.apache.slider.server.appmaster.SliderAppMaster; +import org.apache.slider.server.appmaster.operations.AbstractRMOperation; +import org.apache.slider.server.appmaster.operations.ContainerReleaseOperation; +import org.apache.slider.server.appmaster.state.AppState; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class ActionKillContainer extends AsyncAction { + + private final ContainerId containerId; + + public ActionKillContainer(ContainerId containerId, long delay, + TimeUnit timeUnit) { + super("kill container", delay, timeUnit); + this.containerId = containerId; + } + + @Override + public void execute(SliderAppMaster appMaster, + QueueAccess queueService, + AppState appState) throws Exception { + List<AbstractRMOperation> opsList = new LinkedList<>(); + ContainerReleaseOperation release = new ContainerReleaseOperation(containerId); + opsList.add(release); + //now apply the operations + appMaster.executeRMOperations(opsList); + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosEntry.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosEntry.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosEntry.java index 779cca1..13bda57 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosEntry.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosEntry.java @@ -18,18 +18,67 @@ package org.apache.slider.server.appmaster.monkey; +import com.codahale.metrics.Counter; +import com.codahale.metrics.MetricRegistry; +import com.google.common.base.Preconditions; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Entry in the chaos list */ public class ChaosEntry { - + + protected static final Logger log = + LoggerFactory.getLogger(ChaosEntry.class); public final String name; public final ChaosTarget target; public final long probability; - public ChaosEntry(String name, ChaosTarget target, long probability) { + private final MetricRegistry metrics; + private final Counter invocationCounter; + + + /** + * Constructor -includes validaton of all arguments + * @param name + * @param target + * @param probability + */ + public ChaosEntry(String name, ChaosTarget target, long probability, + MetricRegistry metrics) { + Preconditions.checkArgument(!StringUtils.isEmpty(name), "missing name"); + Preconditions.checkArgument(target != null, "null target"); + Preconditions.checkArgument(probability > 0, "negative probability"); + Preconditions.checkArgument(probability < 10000, "probability over 100%"); this.name = name; this.target = target; this.probability = probability; + this.metrics = metrics; + invocationCounter = + metrics.counter(MetricRegistry.name(ChaosEntry.class, name)); + } + + /** + * Trigger the chaos action + */ + public void invokeChaos() { + log.info("Invoking {}", name); + invocationCounter.inc(); + target.chaosAction(); + } + + /** + * Invoke Chaos if the trigger value is in range of the probability + * @param trigger trigger value, 0-10K + * @return true if the chaos method was invoked + */ + public boolean maybeInvokeChaos(long trigger) { + if (probability < 0) { + invokeChaos(); + return true; + } + return false; } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillAM.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillAM.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillAM.java new file mode 100644 index 0000000..c464ac3 --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillAM.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.slider.server.appmaster.monkey; + +import org.apache.slider.server.appmaster.SliderAppMaster; +import org.apache.slider.server.appmaster.actions.ActionHalt; +import org.apache.slider.server.appmaster.actions.QueueAccess; + +import java.util.concurrent.TimeUnit; + +public class ChaosKillAM implements ChaosTarget { + + private final SliderAppMaster appMaster; + private final QueueAccess queues; + private final int exitCode; + + public ChaosKillAM(SliderAppMaster appMaster, + QueueAccess queues, int exitCode) { + this.appMaster = appMaster; + this.queues = queues; + this.exitCode = exitCode; + } + + /** + * Trigger a delayed halt + */ + @Override + public void chaosAction() { + queues.schedule(new ActionHalt(exitCode, "Chaos invoked halt", 1000, + TimeUnit.MILLISECONDS)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java new file mode 100644 index 0000000..0ffcc8a --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosKillContainer.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.slider.server.appmaster.monkey; + +import org.apache.slider.server.appmaster.SliderAppMaster; +import org.apache.slider.server.appmaster.actions.ActionKillContainer; +import org.apache.slider.server.appmaster.actions.QueueAccess; +import org.apache.slider.server.appmaster.state.RoleInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +/** + * Kill a container + */ +public class ChaosKillContainer implements ChaosTarget { + protected static final Logger log = + LoggerFactory.getLogger(ChaosKillContainer.class); + private final SliderAppMaster appMaster; + private final QueueAccess queues; + private final Random random = new Random(); + + public ChaosKillContainer(SliderAppMaster appMaster, + QueueAccess queues) { + this.appMaster = appMaster; + this.queues = queues; + } + + /** + * Trigger a container kill halt + */ + + @Override + public void chaosAction() { + List<RoleInstance> liveContainers = + appMaster.getAppState().cloneLiveContainerInfoList(); + int size = liveContainers.size(); + if (size == 0) { + log.info("No containers to kill"); + return; + } + int target = random.nextInt(size); + RoleInstance roleInstance = liveContainers.get(target); + log.info("Killing {}", roleInstance); + + queues.schedule(new ActionKillContainer(roleInstance.getId(), + 100, TimeUnit.MILLISECONDS)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java index 7c5638c..c525d02 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/ChaosMonkeyService.java @@ -19,15 +19,20 @@ package org.apache.slider.server.appmaster.monkey; import com.codahale.metrics.MetricRegistry; -import com.google.common.base.Preconditions; import org.apache.hadoop.service.AbstractService; +import org.apache.slider.server.appmaster.actions.AsyncAction; import org.apache.slider.server.appmaster.actions.QueueAccess; +import org.apache.slider.server.appmaster.actions.RenewingAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; +/** + * A chaos monkey service which will invoke ChaosTarget events + */ public class ChaosMonkeyService extends AbstractService { protected static final Logger log = LoggerFactory.getLogger(ChaosMonkeyService.class); @@ -36,25 +41,33 @@ public class ChaosMonkeyService extends AbstractService { private static final List<ChaosEntry> chaosEntries = new ArrayList<ChaosEntry>(); - + public ChaosMonkeyService(MetricRegistry metrics, QueueAccess queues) { super("ChaosMonkeyService"); this.metrics = metrics; this.queues = queues; } - - @Override - protected void serviceStart() throws Exception { - super.serviceStart(); - + + public synchronized void addTarget(String name, + ChaosTarget target, + long probability) { + + chaosEntries.add(new ChaosEntry(name, target, probability, metrics)); + } + + public void play() { + } - - - public synchronized void addTarget(ChaosTarget target, long probability) { - Preconditions.checkArgument(target != null, "null target"); - Preconditions.checkArgument(probability > 0, "negative probability"); - Preconditions.checkArgument(probability > 10000, "probability over 100%"); + + public RenewingAction<MonkeyPlayAction> getChaosAction(long time, TimeUnit timeUnit) { + RenewingAction<MonkeyPlayAction> action = new RenewingAction<>( + new MonkeyPlayAction(this, 0, TimeUnit.MILLISECONDS), + time, + time, + timeUnit, + 0 + ); + return action; } - } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/MonkeyPlayAction.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/MonkeyPlayAction.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/MonkeyPlayAction.java new file mode 100644 index 0000000..20e4466 --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/monkey/MonkeyPlayAction.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.slider.server.appmaster.monkey; + +import org.apache.slider.server.appmaster.SliderAppMaster; +import org.apache.slider.server.appmaster.actions.AsyncAction; +import org.apache.slider.server.appmaster.actions.QueueAccess; +import org.apache.slider.server.appmaster.state.AppState; + +import java.util.concurrent.TimeUnit; + +/** + * Queueable action which calls {@link ChaosMonkeyService#play()} when + * executed. + */ +public class MonkeyPlayAction extends AsyncAction { + + private final ChaosMonkeyService monkey; + + public MonkeyPlayAction(ChaosMonkeyService monkey, long delay, + TimeUnit timeUnit) { + super("chaos monkey", delay, timeUnit); + this.monkey = monkey; + } + + @Override + public void execute(SliderAppMaster appMaster, + QueueAccess queueService, + AppState appState) throws Exception { + monkey.play(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java index 48f97bb..d616678 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java @@ -101,7 +101,7 @@ public class AppState { * Flag set to indicate the application is live -this only happens * after the buildInstance operation */ - boolean applicationLive = false; + private boolean applicationLive = false; /** * The definition of the instance. Flexing updates the resources section @@ -811,6 +811,10 @@ public class AppState { return activeContainers.remove(id); } + /** + * Clone the live container list. This is synchronized. + * @return a snapshot of the live node list + */ public synchronized List<RoleInstance> cloneLiveContainerInfoList() { List<RoleInstance> allRoleInstances; Collection<RoleInstance> values = getLiveNodes().values(); @@ -818,8 +822,12 @@ public class AppState { return allRoleInstances; } - - + /** + * Lookup live instance by string value of container ID + * @param containerId container ID + * @return the role instance for that container + * @throws NoSuchNodeException if it does not exist + */ public synchronized RoleInstance getLiveInstanceByContainerID(String containerId) throws NoSuchNodeException { Collection<RoleInstance> nodes = getLiveNodes().values(); http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/b111268a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy index 8498ee2..73e9b07 100644 --- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy @@ -37,10 +37,10 @@ import org.junit.Test @CompileStatic @Slf4j class TestStandaloneAgentAM extends AgentMiniClusterTestBase { + @Test public void testStandaloneAgentAM() throws Throwable { - describe "create a masterless AM then get the service and look it up via the AM" //launch fake master