KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > rmi > server > gc > ServerGC


1 package org.sapia.ubik.rmi.server.gc;
2
3 import org.sapia.taskman.PeriodicTaskDescriptor;
4 import org.sapia.taskman.Task;
5 import org.sapia.taskman.TaskContext;
6 import org.sapia.taskman.TaskManager;
7 import org.sapia.taskman.TaskOutput;
8
9 //import org.sapia.ubik.net.ServerAddress;
10
import org.sapia.ubik.rmi.Consts;
11 import org.sapia.ubik.rmi.server.*;
12
13 import java.util.*;
14
15
16 /**
17  * This class implements the server-side distributed garbage
18  * collection algorithm.
19  *
20  * @author Yanick Duchesne
21  * 2002-08-09
22  */

23 public class ServerGC implements Task {
24   /* delay after which client that haved not performed a ping are considered down. */
25   public static final long GC_TIMEOUT = ClientGC.GC_CLEAN_INTERVAL * 3;
26
27   /* interval at which GC checks timed-out clients. */
28   public static final long GC_INTERVAL = ClientGC.GC_CLEAN_INTERVAL * 3;
29   private static long _gcTimeout = GC_TIMEOUT;
30   private static long _gcInterval = GC_INTERVAL;
31   private Map _clientTable = new Hashtable();
32
33   public ServerGC(TaskManager taskman) {
34     if (System.getProperty(Consts.SERVER_GC_INTERVAL) != null) {
35       try {
36         _gcInterval = Integer.parseInt(System.getProperty(
37               Consts.SERVER_GC_INTERVAL)) * 1000;
38       } catch (NumberFormatException JavaDoc e) {
39         //noop
40
}
41     }
42
43     if (System.getProperty(Consts.SERVER_GC_TIMEOUT) != null) {
44       try {
45         _gcTimeout = Integer.parseInt(System.getProperty(
46               Consts.SERVER_GC_TIMEOUT)) * 1000;
47       } catch (NumberFormatException JavaDoc e) {
48         //noop
49
}
50     }
51
52     List desc = new ArrayList();
53     desc.add(new PeriodicTaskDescriptor("UbikRMI.ServerGC", _gcInterval, this));
54     taskman.addTaskDescriptors(desc);
55   }
56
57   public ServerGC(TaskManager taskman, long checkInterval, long timeOut) {
58     _gcInterval = checkInterval;
59     _gcTimeout = timeOut;
60
61     List desc = new ArrayList();
62     desc.add(new PeriodicTaskDescriptor("UbikRMI.ServerGC", _gcInterval, this));
63     taskman.addTaskDescriptors(desc);
64   }
65
66   /**
67    * Returns the number of clients connections held by the client
68    * whose host identifier is given.
69    *
70    * @param address a <code>VmId</code>.
71    *
72    * @return the number of client connection for the given
73    * <code>ServerAddress</code>.
74   // */

75
76   // public synchronized int getClientCount(ServerAddress address) {
77
// return getClientInfo(address).count();
78
// }
79

80   /**
81    * Returns the total number of references held on the given object
82    * identifier.
83    *
84    * @param id a <code>VmId</code>.
85    * @param oid an <code>OID</code>.
86    *
87    * @return a reference count, as an <code>int</code>.
88    */

89   public synchronized int getRefCount(VmId id, OID oid) {
90     return getClientInfo(id).getRefCount(oid);
91   }
92
93   /**
94    * Returns the total number of references held on the given object
95    * by the client whose host corresponds to the passed in <code>VmId</code>.
96    */

97   public synchronized int getSpecificCount(VmId id, OID oid) {
98     return getClientInfo(id).getSpecificCount(oid);
99   }
100
101   /**
102    * Returns true if this instance contains the passed in
103    * <code>VmId</code>.
104    *
105    * @return <code>true</code> if this instance contains the passed in
106    * <code>VmId</code>.
107    */

108   public synchronized boolean containsClient(VmId id) {
109     return _clientTable.containsKey(id);
110   }
111
112   /**
113    * Increments the reference count of the given object identifier,
114    * for the client whose <code>VmId</code> is given.
115    *
116    * @param address the client's <code>VmId</code>.
117    * @param oid the object identifier of whose reference count to
118    * increment.
119    */

120   public synchronized void reference(VmId id, OID oid) {
121     if (Log.isDebug()) {
122       Log.debug(ServerGC.class, "referencing from: " + id + " on object: " +
123         oid);
124     }
125
126     ClientInfo inf = getClientInfo(id);
127     inf.reference(oid);
128   }
129
130   /**
131    * Registers a given object internally so that it is not garbage collected before
132    * clients themselves garbage collect it.
133    *
134    * @param id the <code>VmId</code> of the client to whom a stub
135    * corresponding to the passed in object is returned (this in fact creates
136    * a remote reference on the object).
137    * @param oid the <code>OID</code> that identifies the passed in object
138    * locally.
139    * @param the object for which a stub is eventually returned to the client.
140    */

141   public synchronized void registerRef(VmId id, OID oid, Object JavaDoc o) {
142     if (Log.isDebug()) {
143       Log.debug(ServerGC.class,
144         "reference created from: " + id + " on object: " + oid);
145     }
146
147     ClientInfo inf = getClientInfo(id);
148     inf.registerRef(oid, o);
149   }
150
151   /**
152    * Dereferences a given object identifier.
153    *
154    * @param id the <code>VmId</code> of the client from which the
155    * dereferencing call comes.
156    * @param oid the <code>OID</code> to dereference.
157    */

158   public synchronized void dereference(VmId id, OID oid) {
159     if (Log.isDebug()) {
160       Log.debug(ServerGC.class,
161         "dereferencing from: " + id + " on object: " + oid);
162     }
163
164     ClientInfo inf = getClientInfo(id);
165     inf.dereference(oid);
166   }
167
168   public synchronized void touch(VmId id) {
169     ClientInfo info = (ClientInfo) _clientTable.get(id);
170
171     if (info != null) {
172       info.touch();
173     }
174   }
175
176   public void exec(TaskContext ctx) {
177     ctx.getTaskOutput().debug("runner server GC...");
178     removeTimedOutClients(ctx.getTaskOutput());
179   }
180
181   void clear() {
182     _clientTable.clear();
183     Hub.serverRuntime.objectTable.clear();
184   }
185
186   ClientInfo getClientInfo(VmId id) {
187     ClientInfo inf = (ClientInfo) _clientTable.get(id);
188
189     if (inf == null) {
190       inf = new ClientInfo(id);
191       _clientTable.put(id, inf);
192     }
193
194     return inf;
195   }
196
197   /**
198    * Removes the clients that have not performed a ping for a given amount
199    * of time. This delay can be set through the <code>ubik.rmi.server.gc.timeout</code>
200    * property.
201    */

202   private synchronized void removeTimedOutClients(TaskOutput out) {
203     ClientInfo[] infos = (ClientInfo[]) _clientTable.values().toArray(new ClientInfo[_clientTable.size()]);
204
205     for (int i = 0; i < infos.length; i++) {
206       if (!infos[i].isValid(_gcTimeout)) {
207         if (Log.isInfo()) {
208           out.info("removing timed-out client's references " + infos[i].vmid());
209         }
210
211         infos[i].unregisterRefs();
212         _clientTable.remove(infos[i].vmid());
213       }
214     }
215   }
216
217   ////////////////////////////////////////////////////////////
218
// INNER CLASSES
219
////////////////////////////////////////////////////////////
220
static class Count {
221     int count = 0;
222   }
223
224   static class ClientInfo {
225     private Map _oids = new HashMap();
226     private long _lastAccess = System.currentTimeMillis();
227     private VmId _id;
228
229     ClientInfo(VmId id) {
230       _id = id;
231     }
232
233     VmId vmid() {
234       return _id;
235     }
236
237     synchronized void touch() {
238       _lastAccess = System.currentTimeMillis();
239     }
240
241     synchronized boolean isValid(long timeout) {
242       return (System.currentTimeMillis() - _lastAccess) < timeout;
243     }
244
245     void reference(OID oid) {
246       Count count = (Count) _oids.get(oid);
247
248       if (count == null) {
249         count = new Count();
250         _oids.put(oid, count);
251       }
252
253       count.count++;
254       Hub.serverRuntime.objectTable.reference(oid);
255     }
256
257     void registerRef(OID oid, Object JavaDoc obj) {
258       Count c = new Count();
259       c.count++;
260       _oids.put(oid, c);
261       Hub.serverRuntime.objectTable.register(oid, obj);
262     }
263
264     void dereference(OID oid) {
265       Count count;
266
267       if ((count = (Count) _oids.get(oid)) != null) {
268         Hub.serverRuntime.objectTable.dereference(oid, count.count);
269         _oids.remove(oid);
270       }
271     }
272
273     void unregisterRefs() {
274       OID[] oids = (OID[]) _oids.keySet().toArray(new OID[_oids.size()]);
275
276       for (int i = 0; i < oids.length; i++) {
277         Hub.serverRuntime.objectTable.dereference(oids[i],
278           ((Count) _oids.get(oids[i])).count);
279       }
280
281       _oids.clear();
282     }
283
284     int getSpecificCount(OID oid) {
285       Count c = (Count) _oids.get(oid);
286
287       if (c == null) {
288         return 0;
289       } else {
290         return c.count;
291       }
292     }
293
294     int getRefCount(OID oid) {
295       return Hub.serverRuntime.objectTable.getRefCount(oid);
296     }
297   }
298 }
299
Popular Tags