eu.stratosphere.nephele.profiling.impl.JobManagerProfilerImpl.java Source code

Java tutorial

Introduction

Here is the source code for eu.stratosphere.nephele.profiling.impl.JobManagerProfilerImpl.java

Source

/***********************************************************************************************************************
 * 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.profiling.impl;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.stratosphere.configuration.GlobalConfiguration;
import eu.stratosphere.nephele.executiongraph.ExecutionGraph;
import eu.stratosphere.nephele.ipc.RPC;
import eu.stratosphere.nephele.ipc.Server;
import eu.stratosphere.nephele.jobgraph.JobID;
import eu.stratosphere.nephele.profiling.JobManagerProfiler;
import eu.stratosphere.nephele.profiling.ProfilingException;
import eu.stratosphere.nephele.profiling.ProfilingListener;
import eu.stratosphere.nephele.profiling.ProfilingUtils;
import eu.stratosphere.nephele.profiling.impl.types.InternalExecutionVertexThreadProfilingData;
import eu.stratosphere.nephele.profiling.impl.types.InternalInputGateProfilingData;
import eu.stratosphere.nephele.profiling.impl.types.InternalInstanceProfilingData;
import eu.stratosphere.nephele.profiling.impl.types.InternalOutputGateProfilingData;
import eu.stratosphere.nephele.profiling.impl.types.InternalProfilingData;
import eu.stratosphere.nephele.profiling.impl.types.ProfilingDataContainer;
import eu.stratosphere.nephele.profiling.types.InputGateProfilingEvent;
import eu.stratosphere.nephele.profiling.types.InstanceSummaryProfilingEvent;
import eu.stratosphere.nephele.profiling.types.OutputGateProfilingEvent;
import eu.stratosphere.nephele.profiling.types.SingleInstanceProfilingEvent;
import eu.stratosphere.nephele.profiling.types.ThreadProfilingEvent;
import eu.stratosphere.util.StringUtils;

public class JobManagerProfilerImpl implements JobManagerProfiler, ProfilerImplProtocol {

    private static final Log LOG = LogFactory.getLog(JobManagerProfilerImpl.class);

    private static final String RPC_NUM_HANDLER_KEY = "jobmanager.profiling.rpc.numhandler";

    private static final int DEFAULT_NUM_HANLDER = 3;

    private final Server profilingServer;

    private final Map<JobID, List<ProfilingListener>> registeredListeners = new HashMap<JobID, List<ProfilingListener>>();

    private final Map<JobID, JobProfilingData> registeredJobs = new HashMap<JobID, JobProfilingData>();

    public JobManagerProfilerImpl(InetAddress jobManagerbindAddress) throws ProfilingException {

        // Start profiling IPC server
        final int handlerCount = GlobalConfiguration.getInteger(RPC_NUM_HANDLER_KEY, DEFAULT_NUM_HANLDER);
        final int rpcPort = GlobalConfiguration.getInteger(ProfilingUtils.JOBMANAGER_RPC_PORT_KEY,
                ProfilingUtils.JOBMANAGER_DEFAULT_RPC_PORT);

        final InetSocketAddress rpcServerAddress = new InetSocketAddress(jobManagerbindAddress, rpcPort);
        Server profilingServerTmp = null;
        try {

            profilingServerTmp = RPC.getServer(this, rpcServerAddress.getHostName(), rpcServerAddress.getPort(),
                    handlerCount);
            profilingServerTmp.start();
        } catch (IOException ioe) {
            throw new ProfilingException(
                    "Cannot start profiling RPC server: " + StringUtils.stringifyException(ioe));
        }
        this.profilingServer = profilingServerTmp;

    }

    @Override
    public void registerProfilingJob(ExecutionGraph executionGraph) {

        synchronized (this.registeredJobs) {
            this.registeredJobs.put(executionGraph.getJobID(), new JobProfilingData(executionGraph));
        }

    }

    @Override
    public void unregisterProfilingJob(ExecutionGraph executionGraph) {

        synchronized (this.registeredListeners) {
            this.registeredListeners.remove(executionGraph.getJobID());
        }

        synchronized (this.registeredJobs) {
            this.registeredJobs.remove(executionGraph.getJobID());
        }

    }

    @Override
    public void shutdown() {

        // Stop the RPC server
        if (this.profilingServer != null) {
            LOG.debug("Stopping profiling RPC server");
            this.profilingServer.stop();
        }
    }

    private void dispatchThreadData(long timestamp, InternalExecutionVertexThreadProfilingData profilingData) {

        final long profilingStart = getProfilingStart(profilingData.getJobID());
        if (profilingStart < 0 && LOG.isDebugEnabled()) {
            LOG.debug("Received profiling data for unregistered job " + profilingData.getJobID());
            return;
        }

        synchronized (this.registeredListeners) {

            final List<ProfilingListener> jobListeners = this.registeredListeners.get(profilingData.getJobID());
            if (jobListeners == null) {
                return;
            }

            final ThreadProfilingEvent threadProfilingEvent = new ThreadProfilingEvent(profilingData.getUserTime(),
                    profilingData.getSystemTime(), profilingData.getBlockedTime(), profilingData.getWaitedTime(),
                    profilingData.getExecutionVertexID().toManagementVertexID(),
                    profilingData.getProfilingInterval(), profilingData.getJobID(), timestamp,
                    (timestamp - profilingStart));

            final Iterator<ProfilingListener> it = jobListeners.iterator();
            while (it.hasNext()) {
                it.next().processProfilingEvents(threadProfilingEvent);
            }
        }
    }

    private void dispatchInstanceData(long timestamp, InternalInstanceProfilingData profilingData) {

        // Check which of the registered jobs are assigned to that instance
        synchronized (this.registeredJobs) {

            Iterator<JobID> it = this.registeredJobs.keySet().iterator();
            while (it.hasNext()) {
                final JobID jobID = it.next();
                final JobProfilingData jobProfilingData = this.registeredJobs.get(jobID);
                if (!jobProfilingData.instanceAllocatedByJob(profilingData)) {
                    continue;
                }

                final SingleInstanceProfilingEvent singleInstanceProfilingEvent = new SingleInstanceProfilingEvent(
                        profilingData.getProfilingInterval(), profilingData.getIOWaitCPU(),
                        profilingData.getIdleCPU(), profilingData.getUserCPU(), profilingData.getSystemCPU(),
                        profilingData.getHardIrqCPU(), profilingData.getSoftIrqCPU(),
                        profilingData.getTotalMemory(), profilingData.getFreeMemory(),
                        profilingData.getBufferedMemory(), profilingData.getCachedMemory(),
                        profilingData.getCachedSwapMemory(), profilingData.getReceivedBytes(),
                        profilingData.getTransmittedBytes(), jobID, timestamp,
                        timestamp - jobProfilingData.getProfilingStart(),
                        profilingData.getInstanceConnectionInfo().toString());

                synchronized (this.registeredListeners) {

                    List<ProfilingListener> jobListeners = this.registeredListeners.get(jobID);
                    if (jobListeners == null) {
                        continue;
                    }

                    final InstanceSummaryProfilingEvent instanceSummary = jobProfilingData
                            .getInstanceSummaryProfilingData(timestamp);

                    final Iterator<ProfilingListener> listenerIterator = jobListeners.iterator();
                    while (listenerIterator.hasNext()) {
                        final ProfilingListener profilingListener = listenerIterator.next();
                        profilingListener.processProfilingEvents(singleInstanceProfilingEvent);
                        if (instanceSummary != null) {
                            profilingListener.processProfilingEvents(instanceSummary);
                        }
                    }
                }
            }
        }
    }

    private void dispatchInputGateData(long timestamp, InternalInputGateProfilingData profilingData) {

        final long profilingStart = getProfilingStart(profilingData.getJobID());
        if (profilingStart < 0) {
            LOG.error("Received profiling data for unregistered job " + profilingData.getJobID());
            return;
        }

        synchronized (this.registeredListeners) {

            final List<ProfilingListener> jobListeners = this.registeredListeners.get(profilingData.getJobID());
            if (jobListeners == null) {
                return;
            }

            final InputGateProfilingEvent inputGateProfilingEvent = new InputGateProfilingEvent(
                    profilingData.getGateIndex(), profilingData.getNoRecordsAvailableCounter(),
                    profilingData.getExecutionVertexID().toManagementVertexID(),
                    profilingData.getProfilingInterval(), profilingData.getJobID(), timestamp,
                    timestamp - profilingStart);

            final Iterator<ProfilingListener> it = jobListeners.iterator();
            while (it.hasNext()) {
                it.next().processProfilingEvents(inputGateProfilingEvent);
            }
        }
    }

    private void dispatchOutputGateData(long timestamp, InternalOutputGateProfilingData profilingData) {

        final long profilingStart = getProfilingStart(profilingData.getJobID());
        if (profilingStart < 0) {
            LOG.error("Received profiling data for unregistered job " + profilingData.getJobID());
            return;
        }

        synchronized (this.registeredListeners) {

            final List<ProfilingListener> jobListeners = this.registeredListeners.get(profilingData.getJobID());
            if (jobListeners == null) {
                return;
            }

            final OutputGateProfilingEvent outputGateProfilingEvent = new OutputGateProfilingEvent(
                    profilingData.getGateIndex(), profilingData.getChannelCapacityExhaustedCounter(),
                    profilingData.getExecutionVertexID().toManagementVertexID(),
                    profilingData.getProfilingInterval(), profilingData.getJobID(), timestamp,
                    timestamp - profilingStart);

            final Iterator<ProfilingListener> it = jobListeners.iterator();
            while (it.hasNext()) {
                it.next().processProfilingEvents(outputGateProfilingEvent);
            }
        }
    }

    private long getProfilingStart(JobID jobID) {

        synchronized (this.registeredJobs) {

            final JobProfilingData profilingData = this.registeredJobs.get(jobID);
            if (profilingData == null) {
                return -1;
            }

            return profilingData.getProfilingStart();
        }
    }

    @Override
    public void reportProfilingData(ProfilingDataContainer profilingDataContainer) {

        final long timestamp = System.currentTimeMillis();

        // Process the received profiling data
        final Iterator<InternalProfilingData> dataIterator = profilingDataContainer.getIterator();
        while (dataIterator.hasNext()) {

            final InternalProfilingData internalProfilingData = dataIterator.next();

            if (internalProfilingData instanceof InternalExecutionVertexThreadProfilingData) {
                dispatchThreadData(timestamp, (InternalExecutionVertexThreadProfilingData) internalProfilingData);
            } else if (internalProfilingData instanceof InternalInstanceProfilingData) {
                dispatchInstanceData(timestamp, (InternalInstanceProfilingData) internalProfilingData);
            } else if (internalProfilingData instanceof InternalInputGateProfilingData) {
                dispatchInputGateData(timestamp, (InternalInputGateProfilingData) internalProfilingData);
            } else if (internalProfilingData instanceof InternalOutputGateProfilingData) {
                dispatchOutputGateData(timestamp, (InternalOutputGateProfilingData) internalProfilingData);
            } else {
                LOG.error("Received unknown profiling data: " + internalProfilingData.getClass().getName());
            }
        }
    }

    @Override
    public void registerForProfilingData(JobID jobID, ProfilingListener profilingListener) {

        synchronized (this.registeredListeners) {

            List<ProfilingListener> jobListeners = this.registeredListeners.get(jobID);
            if (jobListeners == null) {
                jobListeners = new ArrayList<ProfilingListener>();
                this.registeredListeners.put(jobID, jobListeners);
            }

            jobListeners.add(profilingListener);
        }

    }

    @Override
    public void unregisterFromProfilingData(JobID jobID, ProfilingListener profilingListener) {

        synchronized (this.registeredListeners) {

            List<ProfilingListener> jobListeners = this.registeredListeners.get(jobID);
            if (jobListeners == null) {
                return;
            }

            jobListeners.remove(profilingListener);

            if (jobListeners.isEmpty()) {
                this.registeredListeners.remove(jobID);
            }
        }
    }
}