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.rmi.Consts; 11 import org.sapia.ubik.rmi.server.*; 12 13 import java.util.*; 14 15 16 23 public class ServerGC implements Task { 24 25 public static final long GC_TIMEOUT = ClientGC.GC_CLEAN_INTERVAL * 3; 26 27 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 e) { 39 } 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 e) { 48 } 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 75 76 80 89 public synchronized int getRefCount(VmId id, OID oid) { 90 return getClientInfo(id).getRefCount(oid); 91 } 92 93 97 public synchronized int getSpecificCount(VmId id, OID oid) { 98 return getClientInfo(id).getSpecificCount(oid); 99 } 100 101 108 public synchronized boolean containsClient(VmId id) { 109 return _clientTable.containsKey(id); 110 } 111 112 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 141 public synchronized void registerRef(VmId id, OID oid, Object 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 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 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 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 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 |