Package com.sun.sgs.impl.profile.listener

Source Code of com.sun.sgs.impl.profile.listener.AggregateTaskListener$TaskRunnable

/*
* Copyright 2007-2010 Sun Microsystems, Inc.
*
* This file is part of Project Darkstar Server.
*
* Project Darkstar Server is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation and
* distributed hereunder to you.
*
* Project Darkstar Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* --
*/

package com.sun.sgs.impl.profile.listener;

import com.sun.sgs.auth.Identity;

import com.sun.sgs.impl.profile.util.NetworkReporter;

import com.sun.sgs.impl.sharedutil.PropertiesWrapper;

import com.sun.sgs.kernel.ComponentRegistry;
import com.sun.sgs.kernel.KernelRunnable;
import com.sun.sgs.kernel.RecurringTaskHandle;
import com.sun.sgs.kernel.TaskScheduler;

import com.sun.sgs.profile.ProfileListener;
import com.sun.sgs.profile.ProfileReport;

import java.beans.PropertyChangeEvent;

import java.io.IOException;

import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;


/**
* This implementation of <code>ProfileListener</code> aggregates
* task data over the lifetime of the system, and reports at fixed
* intervals. By default the time interval is 10 seconds.
* <p>
* This listener reports its findings on a server socket. Any number of
* users may connect to that socket to watch the reports. The default
* port used is 43009.
* <p>
* The <code>com.sun.sgs.impl.profile.listener.AggregateTaskListener.</code>
* root is used for all properties in this class. The <code>report.port</code>
* key is used to specify an alternate port on which to report profiling
* data. The <code>report.period</code> key is used to specify the length of
* time, in milliseconds, between reports.
*
* @see SnapshotTaskListener
*/
public class AggregateTaskListener implements ProfileListener {

    // the reporter used to publish data
    private NetworkReporter networkReporter;

    // the handle for the recurring reporting task
    private RecurringTaskHandle handle;

    // the base name for properties
    private static final String PROP_BASE =
        AggregateTaskListener.class.getName();

    // the supported properties and their default values
    private static final String PORT_PROPERTY = PROP_BASE + ".report.port";
    private static final int DEFAULT_PORT = 43009;
    private static final String PERIOD_PROPERTY = PROP_BASE + ".report.period";
    private static final long DEFAULT_PERIOD = 10000;

    private HashMap<String, TaskDetail> map;

    /**
     * Creates an instance of {@code AggregateTaskListener}.
     *
     * @param properties the {@code Properties} for this listener
     * @param owner the {@code Identity} to use for all tasks run by
     *        this listener
     * @param registry the {@code ComponentRegistry} containing the
     *        available system components
     * @throws IOException if the server socket cannot be created
     * @throws IOException if the socket where data will be published
     *                     cannot be created
     */
    public AggregateTaskListener(Properties properties, Identity owner,
                                 ComponentRegistry registry)
        throws IOException
    {
        PropertiesWrapper wrappedProps = new PropertiesWrapper(properties);

        map = new HashMap<String, TaskDetail>();

        int port = wrappedProps.getIntProperty(PORT_PROPERTY, DEFAULT_PORT);
        networkReporter = new NetworkReporter(port);

        long reportPeriod =
            wrappedProps.getLongProperty(PERIOD_PROPERTY, DEFAULT_PERIOD);
        handle = registry.getComponent(TaskScheduler.class).
            scheduleRecurringTask(new TaskRunnable(), owner,
                                  System.currentTimeMillis() + reportPeriod,
                                  reportPeriod);
        handle.start();
    }

    /**
     * {@inheritDoc}
     */
    public void propertyChange(PropertyChangeEvent event) {
  // unused
    }

    /**
     * Records details about successful tasks.
     *
     * @param profileReport the summary for the finished {@code Task}
     */
    public void report(ProfileReport profileReport) {
        if (profileReport.wasTaskSuccessful()) {
            String name = profileReport.getTask().getBaseTaskType();
            if (!name.startsWith("com.sun.sgs.impl.kernel")) {
                synchronized (map) {
                    TaskDetail detail = map.get(name);
                    if (detail == null) {
                        detail = new TaskDetail();
                        map.put(name, detail);
                    }
                    detail.count++;
                    detail.time += profileReport.getRunningTime();
                    detail.opCount +=
                        profileReport.getReportedOperations().size();
                    detail.retries += profileReport.getRetryCount();
        for (String op :
                              profileReport.getReportedOperations())
                    {
                        Long l = detail.ops.get(op);
      detail.ops.put(
           op, Long.valueOf(l == null ? 1 : l + 1));
        }
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void shutdown() {
        networkReporter.shutdown();
    }

    private static class TaskDetail {
        long count = 0;
        long time = 0;
        long opCount = 0;
        long retries = 0;
  Map<String, Long> ops = new HashMap<String, Long>();
 

        public String toString() {
            double avgTime = (double) time / (double) count;
            double avgOps = (double) opCount / (double) count;
      Formatter formatter = new Formatter();
      formatter.format(" avgTime=%2.2fms", avgTime);
      formatter.format(" avgOps=%2.2f", avgOps);
      formatter.format(" avgRetries=%2.2f",
           (double) retries / (double) count);
            if (opCount > 0) {
                formatter.format("%n  ");
            }
      for (String op : ops.keySet()) {
    formatter.format(
        "%s=%2.2f%% ", op,
        100.0 * (double) (ops.get(op).longValue()) /
        (double) opCount);
      }
     
            return formatter.toString();
        }
    }

    /**
     * A runnable for periodically reporting task summaries to the
     * network.
     */
    private class TaskRunnable implements KernelRunnable {
        public String getBaseTaskType() {
            return TaskRunnable.class.getName();
        }
        public void run() throws Exception {
            Formatter reportStr = new Formatter();
            synchronized (map) {
                for (Entry<String, TaskDetail> entry : map.entrySet()) {
                    reportStr.format(
      "%s%s%n", entry.getKey(), entry.getValue());
                }
            }
            reportStr.format("%n");
            networkReporter.report(reportStr.toString());
        }
    }

}
TOP

Related Classes of com.sun.sgs.impl.profile.listener.AggregateTaskListener$TaskRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.