1 /* 2 * Copyright (c) 2001 by Matt Welsh and The Regents of the University of 3 * California. All rights reserved. 4 * 5 * Permission to use, copy, modify, and distribute this software and its 6 * documentation for any purpose, without fee, and without written agreement is 7 * hereby granted, provided that the above copyright notice and the following 8 * two paragraphs appear in all copies of this software. 9 * 10 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR 11 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT 12 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF 13 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 * 15 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 17 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 18 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO 19 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 20 * 21 * Author: Matt Welsh <mdw@cs.berkeley.edu> 22 * 23 */ 24 25 package seda.sandStorm.internal; 26 27 import seda.sandStorm.api.*; 28 import seda.sandStorm.api.internal.*; 29 import seda.sandStorm.core.*; 30 import seda.sandStorm.main.*; 31 import java.util.*; 32 33 /** 34 * This class provides controllers with a view of statistics gathered 35 * by the stage internally during execution. 36 * 37 * @author Matt Welsh 38 */ 39 40 public class StageStats implements StageStatsIF { 41 private static final boolean DEBUG = false; 42 private static final boolean PROFILE = false; 43 44 private static final double SMOOTH_ALPHA = 0.7; 45 private static final int ESTIMATION_SIZE = 100; 46 private static final long ESTIMATION_TIME = 1000; 47 48 /* A handle to the stage. */ 49 StageWrapperIF stage; 50 51 /* Average service rate of events. */ 52 private double serviceRate; 53 54 /* 90th percentile response time of the stage. */ 55 private double rt90thPercentile; 56 57 private boolean first = true; 58 private long lastTime; 59 private int count; 60 private long totalServiceTime, totalEvents, cumulativeEvents; 61 StageStats(StageWrapperIF stage)62 public StageStats(StageWrapperIF stage) { 63 this.stage = stage; 64 reset(); 65 } 66 67 /** Reset all statistics. */ reset()68 public void reset() { 69 serviceRate = 0.0; 70 count = 0; 71 lastTime = System.currentTimeMillis(); 72 totalEvents = totalServiceTime = cumulativeEvents = 0; 73 } 74 75 /** Return a moving average of the service rate. */ getServiceRate()76 public synchronized double getServiceRate() { 77 return serviceRate; 78 } 79 80 /** Get total number of processed events. */ getTotalEvents()81 public synchronized long getTotalEvents() { 82 return this.cumulativeEvents; 83 } 84 85 /** 86 * Record the service time for numEvents taking 'time' msec to 87 * be processed. 88 */ recordServiceRate(int numEvents, long time)89 public synchronized void recordServiceRate(int numEvents, long time) { 90 91 // Only possible to add ourselves to the profile after we start running 92 if (PROFILE && first) { 93 first = false; 94 ManagerIF mgr = Sandstorm.getSandstorm().getManager(); 95 if (mgr.getProfiler() != null) { 96 mgr.getProfiler().add("StageStats serviceRate <"+stage.getStage().getName()+">", 97 new ProfilableIF() { 98 public int profileSize() { 99 return (int)serviceRate; 100 }}); 101 } 102 } 103 104 totalEvents += numEvents; 105 cumulativeEvents += numEvents; 106 totalServiceTime += time; 107 108 count++; 109 long curTime = System.currentTimeMillis(); 110 111 if ((count == ESTIMATION_SIZE) || 112 (curTime - lastTime >= ESTIMATION_TIME)) { 113 if (totalServiceTime == 0) totalServiceTime = 1; 114 double rate = totalEvents / (totalServiceTime * 1.0e-3); 115 serviceRate = (rate * SMOOTH_ALPHA) + (serviceRate * (1.0 - SMOOTH_ALPHA)); 116 if (DEBUG) System.err.println("Stats <"+stage.getStage().getName()+">: numEvents="+totalEvents+" time="+totalServiceTime+", rate="+serviceRate); 117 count = 0; 118 lastTime = curTime; 119 totalEvents = totalServiceTime = 0; 120 } 121 } 122 123 /** Record 90th percentile response time in msec. */ record90thRT(double rt_sample)124 public synchronized void record90thRT(double rt_sample) { 125 this.rt90thPercentile = rt_sample; 126 } 127 128 /** Get 90th percentile response time in msec. */ get90thRT()129 public synchronized double get90thRT() { 130 return this.rt90thPercentile; 131 } 132 133 134 135 } 136 137