KickJava   Java API By Example, From Geeks To Geeks.

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


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.*;
10 import org.sapia.ubik.rmi.Consts;
11 import org.sapia.ubik.rmi.server.*;
12 import org.sapia.ubik.rmi.server.transport.TransportManager;
13
14 import java.lang.ref.*;
15
16 import java.util.*;
17
18
19 /**
20  * This class implements a the client-side distributed garbage
21  * collection algorithm.
22  *
23  * @author Yanick Duchesne
24  * 2002-09-02
25  */

26 public class ClientGC implements Task {
27   /* time at which GC checks for unreferenced objects */
28   public static final long GC_CLEAN_INTERVAL = 10000;
29
30   /* size of OID batches sent to the server */
31   public static final int GC_CLEAN_SIZE = 1000;
32   private long _gcInterval = GC_CLEAN_INTERVAL;
33   private int _gcBatchSize = GC_CLEAN_SIZE;
34   private Map _objByHosts = Collections.synchronizedMap(new HashMap());
35   private long _lastPing = System.currentTimeMillis();
36   private TaskManager _taskMan;
37
38   public ClientGC(TaskManager taskman) {
39     _taskMan = taskman;
40
41     if (System.getProperty(Consts.CLIENT_GC_INTERVAL) != null) {
42       try {
43         _gcInterval = Integer.parseInt(System.getProperty(
44               Consts.CLIENT_GC_INTERVAL)) * 1000;
45       } catch (NumberFormatException JavaDoc e) {
46         //noop
47
}
48
49       try {
50         _gcBatchSize = Integer.parseInt(System.getProperty(
51               Consts.CLIENT_GC_BATCHSIZE));
52       } catch (NumberFormatException JavaDoc e) {
53         //noop
54
}
55     }
56
57     List desc = new ArrayList();
58     desc.add(new PeriodicTaskDescriptor("UbikRMI.ClientGC", _gcInterval, this));
59     _taskMan.addTaskDescriptors(desc);
60   }
61
62   /**
63    * Registers an object identifier, associated to a stub. These mappings are
64    * kept by server(every remote object is kept internally on a per-server basis).
65    *
66    * @param address the <code>ServerAddress</code> representing the server from which
67    * the remote instance comes from.
68    * @param oid the <code>OID</code> of the remote instance to keep.
69    * @param remote the remote instance (a stub) to track.
70    */

71   public synchronized boolean register(ServerAddress address, OID oid,
72     Object JavaDoc remote) {
73     Map hostMap = getHostMap(address);
74
75     if (hostMap.containsKey(oid)) {
76       return false;
77     }
78
79     hostMap.put(oid, new WeakReference(remote));
80
81     return true;
82   }
83
84   private final Map getHostMap(ServerAddress addr) {
85     Map hostMap = (Map) _objByHosts.get(addr);
86
87     if (hostMap == null) {
88       hostMap = Collections.synchronizedMap(new HashMap());
89       _objByHosts.put(addr, hostMap);
90     }
91
92     return hostMap;
93   }
94
95   public void exec(TaskContext ctx) {
96     Set keySet;
97     ServerAddress[] addresses;
98     OID[] oids;
99     OID[] oidsToSend = new OID[_gcBatchSize];
100     int count = 0;
101     Reference ref;
102     Map refs;
103
104     ctx.getTaskOutput().debug("running client GC...");
105
106     keySet = _objByHosts.keySet();
107     addresses = (ServerAddress[]) keySet.toArray(new ServerAddress[keySet.size()]);
108
109     if (Log.isDebug()) {
110       ctx.getTaskOutput().debug("host ids: " + addresses.length);
111     }
112
113     for (int i = 0; i < addresses.length; i++) {
114       refs = (Map) _objByHosts.get(addresses[i]);
115       oids = (OID[]) refs.keySet().toArray(new OID[refs.size()]);
116
117       if (Log.isDebug()) {
118         ctx.getTaskOutput().debug(addresses[i] + " oids: " + oids.length);
119       }
120
121       synchronized (_objByHosts) {
122         if (oids.length == 0) {
123           _objByHosts.remove(addresses[i]);
124
125           break;
126         }
127       }
128
129       for (int j = 0; j < oids.length; j++) {
130         ref = (Reference) refs.get(oids[j]);
131
132         if (ref.get() == null) {
133           if (Log.isInfo()) {
134             ctx.getTaskOutput().debug(oids[j] + " is null");
135           }
136
137           refs.remove(oids[j]);
138           oidsToSend[count++] = oids[j];
139
140           if (count >= oidsToSend.length) {
141             doSend(oidsToSend, count, addresses[i], ctx.getTaskOutput());
142             count = 0;
143           }
144         }
145       }
146
147       doSend(oidsToSend, count, addresses[i], ctx.getTaskOutput());
148       count = 0;
149     }
150   }
151
152   private void doSend(OID[] toSend, int count, ServerAddress addr,
153     TaskOutput out) {
154     if ((count == 0) &&
155           ((System.currentTimeMillis() - _lastPing) < _gcInterval)) {
156       return;
157     }
158
159     Connection conn = null;
160
161     try {
162       if (count > 0) {
163         out.info("sending GC command to " + addr + "; cleaning " + count +
164           " objects");
165       } else {
166         out.info("no garbage; pinging server...");
167       }
168
169       conn = TransportManager.getConnectionsFor(addr).acquire();
170       conn.send(new CommandGc(toSend, count));
171       conn.receive();
172       _lastPing = System.currentTimeMillis();
173       TransportManager.getConnectionsFor(addr).release(conn);
174     } catch (Throwable JavaDoc e) {
175       if (conn != null) {
176         conn.close();
177       }
178     }
179
180     for (int k = 0; k < count; k++) {
181       toSend[k] = null;
182     }
183   }
184 }
185
Popular Tags