KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > web > connector > grizzly > PipelineStatistic


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.web.connector.grizzly;
25
26 import java.util.concurrent.ConcurrentHashMap JavaDoc;
27 import java.util.concurrent.Future JavaDoc;
28 import java.util.concurrent.ScheduledThreadPoolExecutor JavaDoc;
29 import java.util.concurrent.TimeUnit JavaDoc;
30
31 /**
32  * This class is a placeholde for gathering statistic
33  * from a <code>Pipeline</code>
34  *
35  * @author Jean-Francois Arcand
36  */

37 public class PipelineStatistic {
38
39     /**
40      * The port of which we gather statistics
41      */

42     private int port = -1;
43     
44     
45     /**
46      * Is this object started?
47      */

48     private boolean started = false;
49     
50     
51     /**
52      * Maximum pending connection before refusing requests.
53      */

54     private int maxQueueSizeInBytes = -1;
55     
56     
57     /**
58      * The total number of connections queued during the lifetime of the
59      * pipeline
60      */

61     private int totalCount;
62     
63     
64     /**
65      * The largest number of connections that have been in the pipeline
66      * simultaneouly
67      */

68     private int peakCount;
69     
70     
71     /**
72      * Total number of pipeline overflows
73      */

74     private int overflowCount;
75     
76     
77     /**
78      * The Thread Pool used when gathering count statistic.
79      */

80     private ScheduledThreadPoolExecutor JavaDoc countAverageExecutor;
81     
82     
83     /**
84      * Average number of connection queued in that last 1 minute
85      */

86     private Statistic lastMinuteStat = new Statistic(1 * 60);
87     
88     
89     /**
90      * Average number of connection queued in that last 5 minute
91      */

92     private Statistic lastFiveMinuteStat = new Statistic(5 * 60);
93     
94     
95     /**
96      * Average number of connection queued in that last 15 minute
97      */

98     private Statistic lastFifteenMinuteStat = new Statistic(15 * 60);
99     
100     
101     /**
102      * Placeholder to gather statistics.
103      */

104     private ConcurrentHashMap JavaDoc<Integer JavaDoc,Statistic> stats =
105             new ConcurrentHashMap JavaDoc<Integer JavaDoc,Statistic>();
106
107     /**
108      * The pipelines whose stats are being collected
109      */

110     private Pipeline processorPipeline;
111  
112     
113     /**
114      * <code>Future</code> instance in case we need to stop this object.
115      */

116     private Future JavaDoc futures[] = new Future JavaDoc[3];
117
118
119     /**
120      * Total number of connections that have been accepted.
121      */

122     private int totalAcceptCount;
123
124
125     // -------------------------------------------------------------------//
126

127     
128     /**
129      * Constructor
130      *
131      * @param port Port number for which pipeline (connection) stats will be
132      * gathered
133      */

134     public PipelineStatistic(int port) {
135         this.port = port;
136         
137         countAverageExecutor = new ScheduledThreadPoolExecutor JavaDoc(3,
138             new GrizzlyThreadFactory("GrizzlyPipelineStat",
139                 port,Thread.NORM_PRIORITY));
140     }
141     
142     
143     /**
144      * Start gathering statistics.
145      */

146     public void start(){
147         if ( started ) return;
148         
149         futures[0] = countAverageExecutor.scheduleAtFixedRate(lastMinuteStat, 1 ,
150                 lastMinuteStat.getSeconds(), TimeUnit.SECONDS);
151         futures[1] = countAverageExecutor.scheduleAtFixedRate(lastFiveMinuteStat, 1 ,
152                 lastFiveMinuteStat.getSeconds(), TimeUnit.SECONDS);
153         futures[2] = countAverageExecutor.scheduleAtFixedRate(lastFifteenMinuteStat, 1 ,
154                 lastFifteenMinuteStat.getSeconds(), TimeUnit.SECONDS);
155         
156         stats.put(lastMinuteStat.getSeconds(), lastMinuteStat);
157         stats.put(lastFiveMinuteStat.getSeconds(), lastFiveMinuteStat);
158         stats.put(lastFifteenMinuteStat.getSeconds(), lastFifteenMinuteStat);
159         
160         started = true;
161     }
162     
163     
164     /**
165      * Stop gathering statistics.
166      */

167     public void stop(){
168         if ( !started ) return;
169         
170         for (Future JavaDoc future: futures){
171             future.cancel(true);
172         }
173                
174         stats.clear();
175         started = false;
176     }
177     
178     
179     /**
180      * Gather <code>Pipeline</code> statistic.
181      */

182     public boolean gather(int queueLength){
183         if ( queueLength == maxQueueSizeInBytes){
184             overflowCount++;
185             return false;
186         }
187        
188         if ( queueLength > 0 )
189             totalCount++;
190         
191         // Track peak of this Pipeline
192
if (queueLength > peakCount) {
193             peakCount = queueLength;
194         }
195         return true;
196     }
197  
198     
199     /**
200      * Total number of pipeline overflow
201      */

202     public int getCountOverflows(){
203         return overflowCount;
204     }
205      
206      
207     /**
208      * Gets the largest number of connections that were in the queue
209      * simultaneously.
210      *
211      * @return Largest number of connections that were in the queue
212      * simultaneously
213      */

214     public int getPeakQueued(){
215        return peakCount;
216     }
217     
218
219     /**
220      * Gets the maximum size of the connection queue
221      *
222      * @return Maximum size of the connection queue
223      */

224     public int getMaxQueued() {
225         return maxQueueSizeInBytes;
226     }
227
228
229     /**
230      * Gets the total number of connections that have been accepted.
231      *
232      * @return Total number of connections that have been accepted.
233      */

234     public int getCountTotalConnections() {
235         return totalAcceptCount;
236     }
237
238     
239     /**
240      * Set the maximum pending connection this <code>Pipeline</code>
241      * can handle.
242      */

243     public void setQueueSizeInBytes(int maxQueueSizeInBytesCount){
244         this.maxQueueSizeInBytes = maxQueueSizeInBytesCount;
245     }
246     
247     
248     /**
249      * Get the maximum pending connection this <code>Pipeline</code>
250      * can handle.
251      */

252     public int getQueueSizeInBytes(){
253         return maxQueueSizeInBytes;
254     }
255         
256
257     /**
258      * Gets the total number of connections that have been queued.
259      *
260      * A given connection may be queued multiple times, so
261      * <code>counttotalqueued</code> may be greater than or equal to
262      * <code>counttotalconnections</code>.
263      *
264      * @return Total number of connections that have been queued
265      */

266     public int getCountTotalQueued() {
267         return totalCount;
268     }
269     
270
271     /**
272      * Gets the number of connections currently in the queue
273      *
274      * @return Number of connections currently in the queue
275      */

276     public int getCountQueued() {
277         int size = 0;
278
279         if (processorPipeline != null) {
280             size += processorPipeline.size();
281         }
282
283         return size;
284     }
285
286    
287     /**
288      * Gets the total number of ticks that connections have spent in the
289      * queue.
290      *
291      * A tick is a system-dependent unit of time.
292      *
293      * @return Total number of ticks that connections have spent in the
294      * queue
295      */

296     public int getTicksTotalQueued() {
297         return -1; // Not supported
298
}
299
300     
301     /**
302      * Gets the average number of connections queued in the last 1 minute
303      *
304      * @return Average number of connections queued in the last 1 minute
305      */

306     public int getCountQueued1MinuteAverage() {
307         return getCountAverage(1);
308     }
309
310
311     /**
312      * Gets the average number of connections queued in the last 5 minutes
313      *
314      * @return Average number of connections queued in the last 5 minutes
315      */

316     public int getCountQueued5MinuteAverage() {
317         return getCountAverage(5);
318     }
319
320
321     /**
322      * Gets the average number of connections queued in the last 15 minutes
323      *
324      * @return Average number of connections queued in the last 15 minutes
325      */

326     public int getCountQueued15MinuteAverage() {
327         return getCountAverage(15);
328     }
329
330
331     // -------------------------------------------------------------------//
332
// Package protected methods
333

334     void incrementTotalAcceptCount() {
335         totalAcceptCount++;
336     }
337
338     void setProcessorPipeline(Pipeline processorPipeline) {
339         this.processorPipeline = processorPipeline;
340     }
341
342     // -------------------------------------------------------------------//
343
// Private methods
344

345     /**
346      * Gets the average number of connection queued in the last
347      * <code>minutes</code> minutes.
348      *
349      * @param minutes The number of minutes for which the average number of
350      * connections queued is requested
351      *
352      * @return Average number of connections queued
353      */

354     private int getCountAverage(int minutes){
355         Statistic stat = stats.get((minutes * 60));
356         return (stat == null ? 0 : stat.average());
357     }
358
359     
360     /**
361      * Utility class to track average count.
362      */

363     class Statistic implements Runnable JavaDoc{
364                 
365         int lastCount = 0;
366         int average = 0;
367         int seconds;
368              
369         public Statistic(int seconds){
370             this.seconds = seconds;
371         }
372
373                                
374         public void run() {
375             average = totalCount - lastCount;
376             lastCount = totalCount;
377         }
378         
379         public int average(){
380             return average;
381         }
382         
383         
384         public int getSeconds(){
385             return seconds;
386         }
387     }
388     
389     
390 }
391
Popular Tags