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

Source Code of com.sun.sgs.impl.profile.listener.SnapshotParticipantListener$ParticipantCounts

/*
* 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.ProfileParticipantDetail;
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.Entry;
import java.util.Properties;


/**
* This implementation of <code>ProfileListener</code> takes
* snapshots at fixed intervals. It provides a very simple view of
* transactional participants that were active over the last interval. By
* default the time interval is 5 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 43012.
* <p>
* The
* <code>com.sun.sgs.impl.profile.listener.SnapshotParticipantListener</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.
*/
public class SnapshotParticipantListener 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 =
        SnapshotParticipantListener.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 = 43012;
    private static final String PERIOD_PROPERTY = PROP_BASE + ".report.period";
    private static final long DEFAULT_PERIOD = 5000;

    // the map of all participants in the current snapshot window
    private HashMap<String, ParticipantCounts> participantMap;

    // the number of transactional tasks from the current snapshot window
    private int taskCount = 0;

    /**
     * Creates an instance of <code>SnapshotParticipantListener</code>.
     *
     * @param properties the <code>Properties</code> for this listener
     * @param owner the <code>Identity</code> 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
     */
    public SnapshotParticipantListener(Properties properties, Identity owner,
                                       ComponentRegistry registry)
  throws IOException
    {
  PropertiesWrapper wrappedProps = new PropertiesWrapper(properties);

        participantMap = new HashMap<String, ParticipantCounts>();

        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 ParticipantRunnable(), owner,
                                  System.currentTimeMillis() + reportPeriod,
                                  reportPeriod);
        handle.start();
    }

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

    /**
     * {@inheritDoc}
     */
    public void report(ProfileReport profileReport) {
  if (profileReport.wasTaskTransactional()) {
      synchronized (participantMap) {
    taskCount++;
    for (ProfileParticipantDetail detail :
       profileReport.getParticipantDetails())
                {
        ParticipantCounts counts =
      participantMap.get(detail.getParticipantName());
        if (counts == null) {
      counts = new ParticipantCounts();
      participantMap.
          put(detail.getParticipantName(), counts);
        }
        counts.time += detail.getPrepareTime();
        if (detail.wasCommitted()) {
      if (!detail.wasCommittedDirectly()) {
          counts.time += detail.getCommitTime();
                        }
      counts.commits++;
        } else {
      counts.time += detail.getAbortTime();
      counts.aborts++;
        }
    }
      }
  }
    }

    /**
     * Private class used to track values for a single participant.
     */
    private class ParticipantCounts {
  long time = 0;
  int commits = 0;
  int aborts = 0;
  public String toString() {
      double taskTotal = (double) (commits + aborts);
      double participationPct = (taskTotal / (double) taskCount) * 100.0;
      double commitPct = ((double) commits / taskTotal) * 100.0;
      Formatter formatter = new Formatter();
      formatter.format(" participated=%2.2f%%", participationPct);
      formatter.format(" committed=%2.2f%%", commitPct);
      formatter.format(" avgTime=%2.2fms", (double) time / taskTotal);
      return formatter.toString();
  }
    }

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

    /**
     * Private internal class that is used to run a recurring task that
     * reports on the collected data.
     */
    private class ParticipantRunnable implements KernelRunnable {
        public String getBaseTaskType() {
            return ParticipantRunnable.class.getName();
        }
        public void run() throws Exception {
      Formatter reportStr = new Formatter();
      synchronized (participantMap) {
    reportStr.format(
        "Participants for last %d transactional tasks:%n",
        taskCount);
                for (Entry<String, ParticipantCounts> entry :
       participantMap.entrySet())
                {
        reportStr.format(
      "%s%s%n", entry.getKey(), entry.getValue());
                }
    participantMap.clear();
    taskCount = 0;
      }
      reportStr.format("%n");
      networkReporter.report(reportStr.toString());
  }
    }

}
TOP

Related Classes of com.sun.sgs.impl.profile.listener.SnapshotParticipantListener$ParticipantCounts

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.