001/* 002 * Copyright (c) 2016-2017 Chris K Wensel <chris@wensel.net>. All Rights Reserved. 003 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved. 004 * 005 * Project and contact information: http://www.cascading.org/ 006 * 007 * This file is part of the Cascading project. 008 * 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 */ 021 022package cascading.stats; 023 024import java.util.ArrayList; 025import java.util.Collection; 026import java.util.LinkedHashMap; 027import java.util.List; 028import java.util.Map; 029 030import cascading.flow.FlowStep; 031import cascading.management.state.ClientState; 032import cascading.util.ProcessLogger; 033 034/** Class FlowStepStats collects {@link cascading.flow.FlowStep} specific statistics. */ 035public abstract class FlowStepStats extends CascadingStats<FlowNodeStats> 036 { 037 private final FlowStep flowStep; 038 private Map<String, FlowNodeStats> flowNodeStatsMap = new LinkedHashMap<>(); // topologically ordered 039 040 protected FlowStepStats( FlowStep flowStep, ClientState clientState ) 041 { 042 super( flowStep.getName(), clientState ); 043 this.flowStep = flowStep; 044 this.flowStep.setFlowStepStats( this ); 045 } 046 047 @Override 048 protected ProcessLogger getProcessLogger() 049 { 050 if( flowStep != null && flowStep instanceof ProcessLogger ) 051 return (ProcessLogger) flowStep; 052 053 return ProcessLogger.NULL; 054 } 055 056 @Override 057 public String getID() 058 { 059 return flowStep.getID(); 060 } 061 062 @Override 063 public Type getType() 064 { 065 return Type.STEP; 066 } 067 068 public FlowStep getFlowStep() 069 { 070 return flowStep; 071 } 072 073 public void addNodeStats( FlowNodeStats flowNodeStats ) 074 { 075 flowNodeStatsMap.put( flowNodeStats.getID(), flowNodeStats ); 076 } 077 078 protected Map<String, FlowNodeStats> getFlowNodeStatsMap() 079 { 080 return flowNodeStatsMap; 081 } 082 083 public List<FlowNodeStats> getFlowNodeStats() 084 { 085 return new ArrayList<>( flowNodeStatsMap.values() ); 086 } 087 088 public int getNodesCount() 089 { 090 return flowNodeStatsMap.size(); 091 } 092 093 protected Collection<String> getFlowNodeIDs() 094 { 095 return flowNodeStatsMap.keySet(); 096 } 097 098 @Override 099 public Collection<FlowNodeStats> getChildren() 100 { 101 return flowNodeStatsMap.values(); 102 } 103 104 @Override 105 public FlowNodeStats getChildWith( String id ) 106 { 107 return flowNodeStatsMap.get( id ); 108 } 109 110 @Override 111 public synchronized void recordInfo() 112 { 113 clientState.recordFlowStep( flowStep ); 114 } 115 116 @Override 117 public String toString() 118 { 119 return "Step{" + getStatsString() + '}'; 120 } 121 122 public boolean hasCapturedFinalDetail() 123 { 124 Collection<FlowNodeStats> values = flowNodeStatsMap.values(); 125 126 for( FlowNodeStats nodeStats : values ) 127 { 128 if( !nodeStats.getChildren().isEmpty() && !nodeStats.hasCapturedFinalDetail() ) 129 return false; 130 } 131 132 return true; 133 } 134 135 /** 136 * An internal method that will refresh current counters and, if a clientState client is enabled, the child details 137 * including node and slice statistics. 138 * <p> 139 * All results will be then recorded by the clientState implementation. 140 * <p> 141 * See {@link #captureDetail()} to force all statistics to be cached and locally accessible. 142 */ 143 public abstract void recordChildStats(); 144 145 /** 146 * Method getProcessStepID returns the ID representing the under platform process. 147 * <p> 148 * A FlowStep represents a unit of work on a remote platform, in the case of MapReduce, a 149 * MapReduce job. The step ID would be the job id. 150 * 151 * @return a String or null if unavailable 152 */ 153 public abstract String getProcessStepID(); 154 155 public String getProcessStatusURL() 156 { 157 return null; 158 } 159 }