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 26 public class ClientGC implements Task { 27 28 public static final long GC_CLEAN_INTERVAL = 10000; 29 30 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 e) { 46 } 48 49 try { 50 _gcBatchSize = Integer.parseInt(System.getProperty( 51 Consts.CLIENT_GC_BATCHSIZE)); 52 } catch (NumberFormatException e) { 53 } 55 } 56 57 List desc = new ArrayList(); 58 desc.add(new PeriodicTaskDescriptor("UbikRMI.ClientGC", _gcInterval, this)); 59 _taskMan.addTaskDescriptors(desc); 60 } 61 62 71 public synchronized boolean register(ServerAddress address, OID oid, 72 Object 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 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 |