/* * Licensed 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.hadoop.hive.llap.daemon.impl; import java.io.IOException; import java.util.LinkedList; import java.util.List; import com.google.common.base.Preconditions; import org.apache.hadoop.hive.llap.daemon.FinishableStateUpdateHandler; import org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos; import org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.IOSpecProto; import org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.SignableVertexSpec; import org.apache.hadoop.hive.llap.tezplugins.LlapTezUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class QueryFragmentInfo { private static final Logger LOG = LoggerFactory.getLogger(QueryFragmentInfo.class); private final QueryInfo queryInfo; private final String vertexName; private final int fragmentNumber; private final int attemptNumber; private final SignableVertexSpec vertexSpec; private final String fragmentIdString; public QueryFragmentInfo(QueryInfo queryInfo, String vertexName, int fragmentNumber, int attemptNumber, SignableVertexSpec vertexSpec, String fragmentIdString) { Preconditions.checkNotNull(queryInfo); Preconditions.checkNotNull(vertexName); Preconditions.checkNotNull(vertexSpec); this.queryInfo = queryInfo; this.vertexName = vertexName; this.fragmentNumber = fragmentNumber; this.attemptNumber = attemptNumber; this.vertexSpec = vertexSpec; this.fragmentIdString = fragmentIdString; } // Only meant for use by the QueryTracker QueryInfo getQueryInfo() { return this.queryInfo; } public SignableVertexSpec getVertexSpec() { return vertexSpec; } public String getVertexName() { return vertexName; } public int getFragmentNumber() { return fragmentNumber; } public int getAttemptNumber() { return attemptNumber; } public String getFragmentIdentifierString() { return fragmentIdString; } /** * Check whether a task can run to completion or may end up blocking on it's sources. * This currently happens via looking up source state. * TODO: Eventually, this should lookup the Hive Processor to figure out whether * it's reached a state where it can finish - especially in cases of failures * after data has been fetched. * * @return true if the task can finish, false otherwise */ public boolean canFinish() { List<IOSpecProto> inputSpecList = vertexSpec.getInputSpecsList(); boolean canFinish = true; if (inputSpecList != null && !inputSpecList.isEmpty()) { for (IOSpecProto inputSpec : inputSpecList) { if (LlapTezUtils.isSourceOfInterest(inputSpec.getIoDescriptor().getClassName())) { // Lookup the state in the map. LlapDaemonProtocolProtos.SourceStateProto state = queryInfo.getSourceStateMap() .get(inputSpec.getConnectedVertexName()); if (state != null && state == LlapDaemonProtocolProtos.SourceStateProto.S_SUCCEEDED) { continue; } else { if (LOG.isDebugEnabled()) { LOG.debug("Cannot finish due to source: " + inputSpec.getConnectedVertexName()); } canFinish = false; break; } } } } return canFinish; } /** * Get, and create if required, local-dirs for a fragment * @return * @throws IOException */ public String[] getLocalDirs() throws IOException { return queryInfo.getLocalDirs(); } /** * * @param handler * @param lastFinishableState * @return true if the current state is the same as the lastFinishableState. false if the state has already changed. */ public boolean registerForFinishableStateUpdates(FinishableStateUpdateHandler handler, boolean lastFinishableState) { List<String> sourcesOfInterest = new LinkedList<>(); List<IOSpecProto> inputSpecList = vertexSpec.getInputSpecsList(); if (inputSpecList != null && !inputSpecList.isEmpty()) { for (IOSpecProto inputSpec : inputSpecList) { if (LlapTezUtils.isSourceOfInterest(inputSpec.getIoDescriptor().getClassName())) { sourcesOfInterest.add(inputSpec.getConnectedVertexName()); } } } return queryInfo.registerForFinishableStateUpdates(handler, sourcesOfInterest, this, lastFinishableState); } public void unregisterForFinishableStateUpdates(FinishableStateUpdateHandler handler) { queryInfo.unregisterFinishableStateUpdate(handler); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } QueryFragmentInfo that = (QueryFragmentInfo) o; if (fragmentNumber != that.fragmentNumber) { return false; } if (attemptNumber != that.attemptNumber) { return false; } return vertexName.equals(that.vertexName); } @Override public int hashCode() { int result = vertexName.hashCode(); result = 31 * result + fragmentNumber; result = 31 * result + attemptNumber; return result; } }