| /* |
| * 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; |
| } |
| } |