User: juhalindfors
  Date: 01/04/22 05:56:27

  Modified:    src/org/jboss/admin/monitor/graph
                        InvocationTimeGraphModel.java
  Log:
  txMap will no longer grow indefinately.
  Handle clock granularity problem with WinNT (<10ms)
  Handle aggregated invocations correctly (fixes a bug with total invocation
  count displaying wrong values).
  
  Revision  Changes    Path
  1.4       +115 -16   
admin/src/org/jboss/admin/monitor/graph/InvocationTimeGraphModel.java
  
  Index: InvocationTimeGraphModel.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/admin/src/org/jboss/admin/monitor/graph/InvocationTimeGraphModel.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- InvocationTimeGraphModel.java     2001/04/16 21:55:20     1.3
  +++ InvocationTimeGraphModel.java     2001/04/22 12:56:27     1.4
  @@ -7,9 +7,13 @@
   import java.util.Collection;
   import java.util.HashMap;
   import java.util.ArrayList;
  +import javax.swing.SwingUtilities;
   
   // non-standard class dependencies
   import org.jboss.admin.dataholder.InvocationEntry;
  +import org.jboss.admin.monitor.event.GraphModelListener;
  +import org.jboss.admin.monitor.event.GraphModelEvent;
  +import org.jboss.admin.monitor.event.AggregatedInvocationEvent;
   import org.gjt.lindfors.util.BoundBuffer;
   
   
  @@ -18,8 +22,8 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Juha Lindfors</a>
    */
  -public class InvocationTimeGraphModel extends     DefaultGraphModel
  -                                      implements  Runnable {
  +public class InvocationTimeGraphModel extends DefaultGraphModel
  +        implements  Runnable {
                                             
   
       public final static int CONTINUOUS_UPDATE       = 0x1;
  @@ -33,13 +37,16 @@
       private Map  txMap      = Collections.synchronizedMap(new HashMap());
       private List resultList = Collections.synchronizedList(new ArrayList());
       
  -    protected Collection xAxis = new BoundBuffer(1000);
  -    
       private int mode = CONTINUOUS_UPDATE;
       
       private Thread updateThread = null;
       private boolean running = true;
       
  +    private int aggregateCount = 0;
  +    private double aggregateSum   = 0;
  +    
  +    private Object lock = new Object();
  +    
   /*
    *************************************************************************
    *
  @@ -99,7 +106,7 @@
           }
           
           else {
  -            Object value = txMap.get(txID);
  +            Object value = txMap.remove(txID);
               
               if (value == null) {
                   System.out.println("Hmm... this end point didnt have a pair: " + 
txID);
  @@ -108,13 +115,18 @@
               
               long start = ((Long)value).longValue();
               Long diff  = new Long(time-start);
  -            
  -            if (mode == PER_INVOCATION_UPDATE) 
  -                append(diff);
  -            else if (mode == CONTINUOUS_UPDATE)
  +
  +            // deal with clock granularity problem, esp. winnt can't deal
  +            // correctly with anything that runs <10ms.
  +            if (diff.longValue() == 0)
  +                diff = new Long(1);
  +               
  +            //if (mode == PER_INVOCATION_UPDATE) 
  +            //    append(diff);
  +            //else if (mode == CONTINUOUS_UPDATE)
                   resultList.add(diff);
  -            else
  -                throw new InternalError("Unknown mode: " + mode);
  +            //else
  +            //    throw new InternalError("Unknown mode: " + mode);
           }            
       }
   
  @@ -145,8 +157,67 @@
       public void stopContinuousUpdate() {   
           running = false;
           updateThread.interrupt();
  +    }
  +
  +/*
  + *************************************************************************
  + *
  + *      METHOD OVERRIDES
  + *
  + *************************************************************************
  + */     
  +
  +    /*
  +     * Override the append to call our version of the fireValueAppended()
  +     * [TODO] this version is not thread safe
  +     */
  +    public void append(Number number) {
  +        xAxis.add(number);
  +
  +        double avgValue = number.doubleValue();
  +        
  +        if (avgValue  > getVerticalMax())
  +            setVerticalMax(avgValue);
  +
  +        int count  = 0;
  +        double sum = 0.0;
  +        
  +        // store the aggregate values set by the update thread
  +        // and release the thread from the wait status
  +        synchronized(lock) {
  +            count = aggregateCount;
  +            sum   = aggregateSum;
  +            
  +            aggregateCount = 0;
  +            aggregateSum   = 0.0;
  +            
  +            lock.notify();
  +        }
  +        
  +        fireValueAppended(avgValue, sum, count);
  +    }
  +    
  +    /*
  +     * 
  +     */
  +    protected void fireValueAppended(double avgValue, double sum, int count) {
  +                    
  +        // Guaranteed to return a non-null array
  +        Object[] listeners = listenerList.getListenerList();
  +     
  +        // Process the listeners last to first, notifying
  +        // those that are interested in this event
  +        for (int i = listeners.length-2; i >= 0; i -= 2) {
  +            
  +            if (listeners[i] == GraphModelListener.class) {
  +             
  +                GraphModelEvent evt = new AggregatedInvocationEvent(this, avgValue, 
sum, count);
  +                    
  +                ((GraphModelListener)listeners[i+1]).valueAppended(evt);
  +            }
  +        }
       }
  -                                      
  +                                       
   /*
    *************************************************************************
    *
  @@ -180,10 +251,13 @@
           
           Object[] results = null;
           
  +        // lock the result list for atomic copy + clear
           synchronized (resultList) {
               
  -            if (resultList.size() == 0)
  -                resultList.add(new Long(0));
  +            if (resultList.size() == 0) {
  +                super.append(new Long(0));    // generates non-aggregated event
  +                return;
  +            }
                   
               results = resultList.toArray();
               resultList.clear();
  @@ -193,8 +267,33 @@
           
           for (int i = 0; i < results.length; ++i)
               sum += ((Long)results[i]).longValue();
  -
  -        append(new Long(sum / results.length));    
  +        
  +        synchronized(lock) {
  +            // store the aggregate invocation size for event dispatch thread
  +            aggregateCount = results.length;
  +            aggregateSum   = sum;
  +            
  +            final Long average = new Long(sum / results.length);
  +            
  +            // ask the event dispatcher to add the new value to the model and
  +            // fire the required events
  +            SwingUtilities.invokeLater(new Runnable() {
  +                public void run() {
  +                    
  +                    // this is our overridden version of append
  +                    append(average); 
  +                }
  +            });
  +            
  +            // the event dispatcher thread will set this value to zero
  +            // once it has stored it for use in fireValueAppended() method
  +            while (aggregateCount != 0) {
  +                try {
  +                    lock.wait();
  +                }
  +                catch (InterruptedException e) {}
  +            }
  +        }
       }
       
       private String getModeAsString(int mode) {
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to