001: /*
002: * Copyright (c) 2001 by Matt Welsh and The Regents of the University of
003: * California. All rights reserved.
004: *
005: * Permission to use, copy, modify, and distribute this software and its
006: * documentation for any purpose, without fee, and without written agreement is
007: * hereby granted, provided that the above copyright notice and the following
008: * two paragraphs appear in all copies of this software.
009: *
010: * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
011: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
012: * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
013: * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014: *
015: * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
016: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
017: * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
018: * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
019: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
020: *
021: * Author: Matt Welsh <mdw@cs.berkeley.edu>
022: *
023: */
024:
025: package seda.sandStorm.internal;
026:
027: import seda.sandStorm.api.*;
028: import seda.sandStorm.api.internal.*;
029: import seda.sandStorm.core.*;
030: import seda.sandStorm.main.*;
031: import java.util.*;
032:
033: /**
034: * This class provides controllers with a view of statistics gathered
035: * by the stage internally during execution.
036: *
037: * @author Matt Welsh
038: */
039:
040: public class StageStats implements StageStatsIF {
041: private static final boolean DEBUG = false;
042: private static final boolean PROFILE = false;
043:
044: private static final double SMOOTH_ALPHA = 0.7;
045: private static final int ESTIMATION_SIZE = 100;
046: private static final long ESTIMATION_TIME = 1000;
047:
048: /* A handle to the stage. */
049: StageWrapperIF stage;
050:
051: /* Average service rate of events. */
052: private double serviceRate;
053:
054: /* 90th percentile response time of the stage. */
055: private double rt90thPercentile;
056:
057: private boolean first = true;
058: private long lastTime;
059: private int count;
060: private long totalServiceTime, totalEvents, cumulativeEvents;
061:
062: public StageStats(StageWrapperIF stage) {
063: this .stage = stage;
064: reset();
065: }
066:
067: /** Reset all statistics. */
068: public void reset() {
069: serviceRate = 0.0;
070: count = 0;
071: lastTime = System.currentTimeMillis();
072: totalEvents = totalServiceTime = cumulativeEvents = 0;
073: }
074:
075: /** Return a moving average of the service rate. */
076: public synchronized double getServiceRate() {
077: return serviceRate;
078: }
079:
080: /** Get total number of processed events. */
081: public synchronized long getTotalEvents() {
082: return this .cumulativeEvents;
083: }
084:
085: /**
086: * Record the service time for numEvents taking 'time' msec to
087: * be processed.
088: */
089: public synchronized void recordServiceRate(int numEvents, long time) {
090:
091: // Only possible to add ourselves to the profile after we start running
092: if (PROFILE && first) {
093: first = false;
094: ManagerIF mgr = Sandstorm.getSandstorm().getManager();
095: if (mgr.getProfiler() != null) {
096: mgr.getProfiler().add(
097: "StageStats serviceRate <"
098: + stage.getStage().getName() + ">",
099: new ProfilableIF() {
100: public int profileSize() {
101: return (int) serviceRate;
102: }
103: });
104: }
105: }
106:
107: totalEvents += numEvents;
108: cumulativeEvents += numEvents;
109: totalServiceTime += time;
110:
111: count++;
112: long curTime = System.currentTimeMillis();
113:
114: if ((count == ESTIMATION_SIZE)
115: || (curTime - lastTime >= ESTIMATION_TIME)) {
116: if (totalServiceTime == 0)
117: totalServiceTime = 1;
118: double rate = totalEvents / (totalServiceTime * 1.0e-3);
119: serviceRate = (rate * SMOOTH_ALPHA)
120: + (serviceRate * (1.0 - SMOOTH_ALPHA));
121: if (DEBUG)
122: System.err.println("Stats <"
123: + stage.getStage().getName() + ">: numEvents="
124: + totalEvents + " time=" + totalServiceTime
125: + ", rate=" + serviceRate);
126: count = 0;
127: lastTime = curTime;
128: totalEvents = totalServiceTime = 0;
129: }
130: }
131:
132: /** Record 90th percentile response time in msec. */
133: public synchronized void record90thRT(double rt_sample) {
134: this .rt90thPercentile = rt_sample;
135: }
136:
137: /** Get 90th percentile response time in msec. */
138: public synchronized double get90thRT() {
139: return this.rt90thPercentile;
140: }
141:
142: }
|