blob: df4ab8ec95e0d3af6f48732ba58af4af1741ed89 [file] [log] [blame]
/*
* 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.state;
import org.apache.slider.api.StatusKeys;
import org.apache.slider.providers.PlacementPolicy;
import org.apache.slider.providers.ProviderRole;
import java.util.HashMap;
import java.util.Map;
/**
* Models the ongoing status of all nodes in
* Nothing here is synchronized: grab the whole instance to update.
*/
public final class RoleStatus implements Cloneable {
private final String name;
/**
* Role key in the container details stored in the AM,
* currently mapped to priority
*/
private final int key;
private final ProviderRole providerRole;
private int desired, actual, requested, releasing;
private volatile int failed, started, startFailed, completed, totalRequested;
private String failureMessage = "";
public RoleStatus(ProviderRole providerRole) {
this.providerRole = providerRole;
this.name = providerRole.name;
this.key = providerRole.id;
}
public String getName() {
return name;
}
public int getKey() {
return key;
}
public int getPriority() {
return getKey();
}
/**
* Get the placement policy enum, from the values in
* {@link PlacementPolicy}
* @return the placement policy for this role
*/
public int getPlacementPolicy() {
return providerRole.placementPolicy;
}
public boolean getExcludeFromFlexing() {
return 0 != (getPlacementPolicy() & PlacementPolicy.EXCLUDE_FROM_FLEXING);
}
public boolean getNoDataLocality() {
return 0 != (getPlacementPolicy() & PlacementPolicy.NO_DATA_LOCALITY);
}
public int getDesired() {
return desired;
}
public void setDesired(int desired) {
this.desired = desired;
}
public int getActual() {
return actual;
}
public int incActual() {
return ++actual;
}
public int decActual() {
if (0 > --actual) {
actual = 0;
}
return actual;
}
public synchronized int getRequested() {
return requested;
}
public synchronized int incRequested() {
totalRequested++;
return ++requested;
}
public synchronized int decRequested() {
if (0 > --requested) {
requested = 0;
}
return requested;
}
public int getReleasing() {
return releasing;
}
public int incReleasing() {
return ++releasing;
}
public int decReleasing() {
if (0 > --releasing) {
releasing = 0;
}
return releasing;
}
public int getFailed() {
return failed;
}
/**
* Reset the failure counts
* @return the total number of failures up to this point
*/
public int resetFailed() {
int total = failed + startFailed;
failed = 0;
startFailed = 0;
return total;
}
/**
* Note that a role failed, text will
* be used in any diagnostics if an exception
* is later raised.
* @param startupFailure flag to indicate this was a startup event
* @return the number of failures
* @param text text about the failure
*/
public int noteFailed(boolean startupFailure, String text) {
int current = ++failed;
if (text != null) {
failureMessage = text;
}
//have a look to see if it short lived
if (startupFailure) {
incStartFailed();
}
return current;
}
public int getStartFailed() {
return startFailed;
}
public void incStartFailed() {
startFailed++;
}
public String getFailureMessage() {
return failureMessage;
}
public int getCompleted() {
return completed;
}
public void setCompleted(int completed) {
this.completed = completed;
}
public int incCompleted() {
return completed ++;
}
public int getStarted() {
return started;
}
public void incStarted() {
started++;
}
public int getTotalRequested() {
return totalRequested;
}
/**
* Get the number of roles we are short of.
* nodes released are ignored.
* @return the positive or negative number of roles to add/release.
* 0 means "do nothing".
*/
public synchronized int getDelta() {
int inuse = actual + requested;
//don't know how to view these. Are they in-use or not?
//inuse += releasing;
int delta = desired - inuse;
if (delta < 0) {
//if we are releasing, remove the number that are already released.
delta += releasing;
//but never switch to a positive
delta = Math.min(delta, 0);
}
return delta;
}
@Override
public String toString() {
return "RoleStatus{" +
"name='" + name + '\'' +
", key=" + key +
", desired=" + desired +
", actual=" + actual +
", requested=" + requested +
", releasing=" + releasing +
", failed=" + failed +
", started=" + started +
", startFailed=" + startFailed +
", completed=" + completed +
", failureMessage='" + failureMessage + '\'' +
'}';
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* Get the provider role
* @return
*/
public ProviderRole getProviderRole() {
return providerRole;
}
/**
* Build the statistics map from the current data
* @return a map for use in statistics reports
*/
public Map<String, Integer> buildStatistics() {
Map<String, Integer> stats = new HashMap<String, Integer>();
stats.put(StatusKeys.STATISTICS_CONTAINERS_ACTIVE_REQUESTS, getRequested());
stats.put(StatusKeys.STATISTICS_CONTAINERS_COMPLETED, getCompleted());
stats.put(StatusKeys.STATISTICS_CONTAINERS_DESIRED, getDesired());
stats.put(StatusKeys.STATISTICS_CONTAINERS_FAILED, getFailed());
stats.put(StatusKeys.STATISTICS_CONTAINERS_LIVE, getActual());
stats.put(StatusKeys.STATISTICS_CONTAINERS_REQUESTED, getTotalRequested());
stats.put(StatusKeys.STATISTICS_CONTAINERS_STARTED, getStarted());
stats.put(StatusKeys.STATISTICS_CONTAINERS_START_FAILED, getStartFailed());
return stats;
}
}