KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > transport > CorbaConnectionCacheBase


1 /*
2  * @(#)CorbaConnectionCacheBase.java 1.25 04/06/21
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.transport;
9
10 import java.util.Collection JavaDoc;
11 import java.util.Iterator JavaDoc;
12
13 import com.sun.corba.se.pept.broker.Broker;
14 import com.sun.corba.se.pept.transport.Connection;
15 import com.sun.corba.se.pept.transport.ConnectionCache;
16
17 import com.sun.corba.se.spi.logging.CORBALogDomains;
18 import com.sun.corba.se.spi.orb.ORB;
19 import com.sun.corba.se.spi.transport.CorbaConnectionCache;
20
21 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
22 import com.sun.corba.se.impl.orbutil.ORBUtility;
23
24 /**
25  * @author Harold Carr
26  */

27 public abstract class CorbaConnectionCacheBase
28     implements
29     ConnectionCache,
30     CorbaConnectionCache
31 {
32     protected ORB orb;
33     protected long timestamp = 0;
34     protected String JavaDoc cacheType;
35     protected String JavaDoc monitoringName;
36     protected ORBUtilSystemException wrapper;
37
38     protected CorbaConnectionCacheBase(ORB orb, String JavaDoc cacheType,
39                        String JavaDoc monitoringName)
40     {
41     this.orb = orb;
42     this.cacheType = cacheType;
43     this.monitoringName = monitoringName;
44     wrapper =ORBUtilSystemException.get(orb,CORBALogDomains.RPC_TRANSPORT);
45     registerWithMonitoring();
46     dprintCreation();
47     }
48     
49     ////////////////////////////////////////////////////
50
//
51
// pept.transport.ConnectionCache
52
//
53

54     public String JavaDoc getCacheType()
55     {
56     return cacheType;
57     }
58
59     public synchronized void stampTime(Connection c)
60     {
61     // _REVISIT_ Need to worry about wrap around some day
62
c.setTimeStamp(timestamp++);
63     }
64
65     public long numberOfConnections()
66     {
67     synchronized (backingStore()) {
68         return values().size();
69     }
70     }
71
72     public long numberOfIdleConnections()
73     {
74     long count = 0;
75     synchronized (backingStore()) {
76         Iterator JavaDoc connections = values().iterator();
77         while (connections.hasNext()) {
78         if (! ((Connection)connections.next()).isBusy()) {
79             count++;
80         }
81         }
82     }
83     return count;
84     }
85
86     public long numberOfBusyConnections()
87     {
88     long count = 0;
89     synchronized (backingStore()) {
90         Iterator JavaDoc connections = values().iterator();
91         while (connections.hasNext()) {
92         if (((Connection)connections.next()).isBusy()) {
93             count++;
94         }
95         }
96     }
97     return count;
98     }
99
100     /**
101      * Discarding least recently used Connections that are not busy
102      *
103      * This method must be synchronized since one WorkerThread could
104      * be reclaming connections inside the synchronized backingStore
105      * block and a second WorkerThread (or a SelectorThread) could have
106      * already executed the if (numberOfConnections <= .... ). As a
107      * result the second thread would also attempt to reclaim connections.
108      *
109      * If connection reclamation becomes a performance issue, the connection
110      * reclamation could make its own task and consequently executed in
111      * a separate thread.
112      * Currently, the accept & reclaim are done in the same thread, WorkerThread
113      * by default. It could be changed such that the SelectorThread would do
114      * it for SocketChannels and WorkerThreads for Sockets by updating the
115      * ParserTable.
116      */

117     synchronized public boolean reclaim()
118     {
119     try {
120         long numberOfConnections = numberOfConnections();
121
122         if (orb.transportDebugFlag) {
123         dprint(".reclaim->: " + numberOfConnections
124             + " ("
125             + orb.getORBData().getHighWaterMark()
126             + "/"
127             + orb.getORBData().getLowWaterMark()
128             + "/"
129             + orb.getORBData().getNumberToReclaim()
130             + ")");
131         }
132
133         if (numberOfConnections <= orb.getORBData().getHighWaterMark() ||
134         numberOfConnections < orb.getORBData().getLowWaterMark()) {
135         return false;
136         }
137         
138         Object JavaDoc backingStore = backingStore();
139         synchronized (backingStore) {
140
141              // REVISIT - A less expensive alternative connection reclaiming
142
// algorithm could be investigated.
143

144         for (int i=0; i < orb.getORBData().getNumberToReclaim(); i++) {
145             Connection toClose = null;
146             long lru = java.lang.Long.MAX_VALUE;
147             Iterator JavaDoc iterator = values().iterator();
148             
149             // Find least recently used and not busy connection in cache
150
while ( iterator.hasNext() ) {
151             Connection c = (Connection) iterator.next();
152             if ( !c.isBusy() && c.getTimeStamp() < lru ) {
153                 toClose = c;
154                 lru = c.getTimeStamp();
155             }
156             }
157             
158             if ( toClose == null ) {
159             return false;
160             }
161             
162             try {
163             if (orb.transportDebugFlag) {
164                 dprint(".reclaim: closing: " + toClose);
165             }
166             toClose.close();
167             } catch (Exception JavaDoc ex) {
168             // REVISIT - log
169
}
170         }
171
172         if (orb.transportDebugFlag) {
173             dprint(".reclaim: connections reclaimed ("
174                 + (numberOfConnections - numberOfConnections()) + ")");
175         }
176         }
177
178         // XXX is necessary to do a GC to reclaim
179
// closed network connections ??
180
// java.lang.System.gc();
181

182         return true;
183     } finally {
184         if (orb.transportDebugFlag) {
185         dprint(".reclaim<-: " + numberOfConnections());
186         }
187     }
188     }
189
190     ////////////////////////////////////////////////////
191
//
192
// spi.transport.ConnectionCache
193
//
194

195     public String JavaDoc getMonitoringName()
196     {
197     return monitoringName;
198     }
199
200     ////////////////////////////////////////////////////
201
//
202
// Implementation
203
//
204

205     // This is public so folb.Server test can access it.
206
public abstract Collection JavaDoc values();
207
208     protected abstract Object JavaDoc backingStore();
209
210     protected abstract void registerWithMonitoring();
211
212     protected void dprintCreation()
213     {
214     if (orb.transportDebugFlag) {
215         dprint(".constructor: cacheType: " + getCacheType()
216            + " monitoringName: " + getMonitoringName());
217     }
218     }
219
220     protected void dprintStatistics()
221     {
222     if (orb.transportDebugFlag) {
223         dprint(".stats: "
224            + numberOfConnections() + "/total "
225            + numberOfBusyConnections() + "/busy "
226            + numberOfIdleConnections() + "/idle"
227            + " ("
228            + orb.getORBData().getHighWaterMark() + "/"
229            + orb.getORBData().getLowWaterMark() + "/"
230            + orb.getORBData().getNumberToReclaim()
231            + ")");
232     }
233     }
234
235     protected void dprint(String JavaDoc msg)
236     {
237     ORBUtility.dprint("CorbaConnectionCacheBase", msg);
238     }
239 }
240
241 // End of file.
242
Popular Tags