/*********************************************************************************************************************** * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu) * * 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 eu.stratosphere.nephele.instance; import java.io.IOException; import java.net.InetSocketAddress; import java.util.List; import java.util.Set; import eu.stratosphere.nephele.deployment.TaskDeploymentDescriptor; import eu.stratosphere.nephele.execution.librarycache.LibraryCacheManager; import eu.stratosphere.nephele.execution.librarycache.LibraryCacheProfileRequest; import eu.stratosphere.nephele.execution.librarycache.LibraryCacheProfileResponse; import eu.stratosphere.nephele.execution.librarycache.LibraryCacheUpdate; import eu.stratosphere.nephele.executiongraph.ExecutionVertexID; import eu.stratosphere.nephele.taskmanager.TaskKillResult; import eu.stratosphere.runtime.io.channels.ChannelID; import eu.stratosphere.nephele.ipc.RPC; import eu.stratosphere.nephele.jobgraph.JobID; import eu.stratosphere.nephele.net.NetUtils; import eu.stratosphere.nephele.protocols.TaskOperationProtocol; import eu.stratosphere.nephele.taskmanager.TaskCancelResult; import eu.stratosphere.nephele.taskmanager.TaskSubmissionResult; import eu.stratosphere.nephele.topology.NetworkNode; import eu.stratosphere.nephele.topology.NetworkTopology; /** * An abstract instance represents a resource a {@link eu.stratosphere.nephele.taskmanager.TaskManager} runs on. * */ public abstract class AbstractInstance extends NetworkNode { /** * The type of the instance. */ private final InstanceType instanceType; /** * The connection info identifying the instance. */ private final InstanceConnectionInfo instanceConnectionInfo; /** * The hardware description as reported by the instance itself. */ private final HardwareDescription hardwareDescription; /** * Stores the RPC stub object for the instance's task manager. */ private TaskOperationProtocol taskManager = null; /** * Constructs an abstract instance object. * * @param instanceType * the type of the instance * @param instanceConnectionInfo * the connection info identifying the instance * @param parentNode * the parent node in the network topology * @param networkTopology * the network topology this node is a part of * @param hardwareDescription * the hardware description provided by the instance itself */ public AbstractInstance(final InstanceType instanceType, final InstanceConnectionInfo instanceConnectionInfo, final NetworkNode parentNode, final NetworkTopology networkTopology, final HardwareDescription hardwareDescription) { super((instanceConnectionInfo == null) ? null : instanceConnectionInfo.toString(), parentNode, networkTopology); this.instanceType = instanceType; this.instanceConnectionInfo = instanceConnectionInfo; this.hardwareDescription = hardwareDescription; } /** * Creates or returns the RPC stub object for the instance's task manager. * * @return the RPC stub object for the instance's task manager * @throws IOException * thrown if the RPC stub object for the task manager cannot be created */ private TaskOperationProtocol getTaskManagerProxy() throws IOException { if (this.taskManager == null) { this.taskManager = RPC.getProxy(TaskOperationProtocol.class, new InetSocketAddress(getInstanceConnectionInfo().address(), getInstanceConnectionInfo().ipcPort()), NetUtils.getSocketFactory()); } return this.taskManager; } /** * Destroys and removes the RPC stub object for this instance's task manager. */ private void destroyTaskManagerProxy() { if (this.taskManager != null) { RPC.stopProxy(this.taskManager); this.taskManager = null; } } /** * Returns the type of the instance. * * @return the type of the instance */ public final InstanceType getType() { return this.instanceType; } /** * Returns the instance's connection information object. * * @return the instance's connection information object */ public final InstanceConnectionInfo getInstanceConnectionInfo() { return this.instanceConnectionInfo; } /** * Returns the instance's hardware description as reported by the instance itself. * * @return the instance's hardware description */ public HardwareDescription getHardwareDescription() { return this.hardwareDescription; } /** * Checks if all the libraries required to run the job with the given * job ID are available on this instance. Any libary that is missing * is transferred to the instance as a result of this call. * * @param jobID * the ID of the job whose libraries are to be checked for * @throws IOException * thrown if an error occurs while checking for the libraries */ public synchronized void checkLibraryAvailability(final JobID jobID) throws IOException { // Now distribute the required libraries for the job String[] requiredLibraries = LibraryCacheManager.getRequiredJarFiles(jobID); if (requiredLibraries == null) { throw new IOException("No entry of required libraries for job " + jobID); } LibraryCacheProfileRequest request = new LibraryCacheProfileRequest(); request.setRequiredLibraries(requiredLibraries); // Send the request LibraryCacheProfileResponse response = null; response = getTaskManagerProxy().getLibraryCacheProfile(request); // Check response and transfer libraries if necessary for (int k = 0; k < requiredLibraries.length; k++) { if (!response.isCached(k)) { LibraryCacheUpdate update = new LibraryCacheUpdate(requiredLibraries[k]); getTaskManagerProxy().updateLibraryCache(update); } } } /** * Submits a list of tasks to the instance's {@link eu.stratosphere.nephele.taskmanager.TaskManager}. * * @param tasks * the list of tasks to be submitted * @return the result of the submission attempt * @throws IOException * thrown if an error occurs while transmitting the task */ public synchronized List<TaskSubmissionResult> submitTasks(final List<TaskDeploymentDescriptor> tasks) throws IOException { return getTaskManagerProxy().submitTasks(tasks); } /** * Cancels the task identified by the given ID at the instance's * {@link eu.stratosphere.nephele.taskmanager.TaskManager}. * * @param id * the ID identifying the task to be canceled * @throws IOException * thrown if an error occurs while transmitting the request or receiving the response * @return the result of the cancel attempt */ public synchronized TaskCancelResult cancelTask(final ExecutionVertexID id) throws IOException { return getTaskManagerProxy().cancelTask(id); } /** * Kills the task identified by the given ID at the instance's * {@link eu.stratosphere.nephele.taskmanager.TaskManager}. * * @param id * the ID identifying the task to be killed * @throws IOException * thrown if an error occurs while transmitting the request or receiving the response * @return the result of the kill attempt */ public synchronized TaskKillResult killTask(final ExecutionVertexID id) throws IOException { return getTaskManagerProxy().killTask(id); } @Override public boolean equals(final Object obj) { // Fall back since dummy instances do not have a instanceConnectionInfo if (this.instanceConnectionInfo == null) { return super.equals(obj); } if (!(obj instanceof AbstractInstance)) { return false; } final AbstractInstance abstractInstance = (AbstractInstance) obj; return this.instanceConnectionInfo.equals(abstractInstance.getInstanceConnectionInfo()); } @Override public int hashCode() { // Fall back since dummy instances do not have a instanceConnectionInfo if (this.instanceConnectionInfo == null) { return super.hashCode(); } return this.instanceConnectionInfo.hashCode(); } /** * Triggers the remote task manager to print out the current utilization of its read and write buffers to its logs. * * @throws IOException * thrown if an error occurs while transmitting the request */ public synchronized void logBufferUtilization() throws IOException { getTaskManagerProxy().logBufferUtilization(); } /** * Kills the task manager running on this instance. This method is mainly intended to test and debug Nephele's fault * tolerance mechanisms. * * @throws IOException * thrown if an error occurs while transmitting the request */ public synchronized void killTaskManager() throws IOException { getTaskManagerProxy().killTaskManager(); } /** * Invalidates the entries identified by the given channel IDs from the remote task manager's receiver lookup cache. * * @param channelIDs * the channel IDs identifying the cache entries to invalidate * @throws IOException * thrown if an error occurs during this remote procedure call */ public synchronized void invalidateLookupCacheEntries(final Set<ChannelID> channelIDs) throws IOException { getTaskManagerProxy().invalidateLookupCacheEntries(channelIDs); } /** * Destroys all RPC stub objects attached to this instance. */ public synchronized void destroyProxies() { destroyTaskManagerProxy(); } }