FileDocCategorySizeDatePackage
CorbaConnectionCacheBase.javaAPI DocJava SE 5 API6294Fri Aug 26 14:54:32 BST 2005com.sun.corba.se.impl.transport

CorbaConnectionCacheBase

public abstract class CorbaConnectionCacheBase extends Object implements com.sun.corba.se.spi.transport.CorbaConnectionCache, com.sun.corba.se.pept.transport.ConnectionCache
author
Harold Carr

Fields Summary
protected com.sun.corba.se.spi.orb.ORB
orb
protected long
timestamp
protected String
cacheType
protected String
monitoringName
protected com.sun.corba.se.impl.logging.ORBUtilSystemException
wrapper
Constructors Summary
protected CorbaConnectionCacheBase(com.sun.corba.se.spi.orb.ORB orb, String cacheType, String monitoringName)


        
				        
    
	this.orb = orb;
	this.cacheType = cacheType;
	this.monitoringName = monitoringName;
	wrapper =ORBUtilSystemException.get(orb,CORBALogDomains.RPC_TRANSPORT);
	registerWithMonitoring();
	dprintCreation();
    
Methods Summary
protected abstract java.lang.ObjectbackingStore()

protected voiddprint(java.lang.String msg)

	ORBUtility.dprint("CorbaConnectionCacheBase", msg);
    
protected voiddprintCreation()

	if (orb.transportDebugFlag) {
	    dprint(".constructor: cacheType: " + getCacheType()
		   + " monitoringName: " + getMonitoringName());
	}
    
protected voiddprintStatistics()

	if (orb.transportDebugFlag) {
	    dprint(".stats: "
		   + numberOfConnections() + "/total "
		   + numberOfBusyConnections() + "/busy "
		   + numberOfIdleConnections() + "/idle"
		   + " (" 
		   + orb.getORBData().getHighWaterMark() + "/"
		   + orb.getORBData().getLowWaterMark() + "/"
		   + orb.getORBData().getNumberToReclaim() 
		   + ")");
	}
    
public java.lang.StringgetCacheType()

	return cacheType;
    
public java.lang.StringgetMonitoringName()

	return monitoringName;
    
public longnumberOfBusyConnections()

	long count = 0;
	synchronized (backingStore()) {
	    Iterator connections = values().iterator();
	    while (connections.hasNext()) {
		if (((Connection)connections.next()).isBusy()) {
		    count++;
		}
	    }
	}
	return count;
    
public longnumberOfConnections()

	synchronized (backingStore()) {
	    return values().size();
	}
    
public longnumberOfIdleConnections()

	long count = 0;
	synchronized (backingStore()) {
	    Iterator connections = values().iterator();
	    while (connections.hasNext()) {
		if (! ((Connection)connections.next()).isBusy()) {
		    count++;
		}
	    }
	}
	return count;
    
public synchronized booleanreclaim()
Discarding least recently used Connections that are not busy This method must be synchronized since one WorkerThread could be reclaming connections inside the synchronized backingStore block and a second WorkerThread (or a SelectorThread) could have already executed the if (numberOfConnections <= .... ). As a result the second thread would also attempt to reclaim connections. If connection reclamation becomes a performance issue, the connection reclamation could make its own task and consequently executed in a separate thread. Currently, the accept & reclaim are done in the same thread, WorkerThread by default. It could be changed such that the SelectorThread would do it for SocketChannels and WorkerThreads for Sockets by updating the ParserTable.

	try {
	    long numberOfConnections = numberOfConnections();

	    if (orb.transportDebugFlag) {
		dprint(".reclaim->: " + numberOfConnections
			+ " ("
			+ orb.getORBData().getHighWaterMark()
			+ "/"
			+ orb.getORBData().getLowWaterMark()
			+ "/"
			+ orb.getORBData().getNumberToReclaim()
			+ ")");
	    }

	    if (numberOfConnections <= orb.getORBData().getHighWaterMark() ||
		numberOfConnections < orb.getORBData().getLowWaterMark()) {
		return false;
	    }
	    
	    Object backingStore = backingStore();
	    synchronized (backingStore) {

	         // REVISIT - A less expensive alternative connection reclaiming 
	         //           algorithm could be investigated.

		for (int i=0; i < orb.getORBData().getNumberToReclaim(); i++) {
		    Connection toClose = null;
		    long lru = java.lang.Long.MAX_VALUE;
		    Iterator iterator = values().iterator();
		    
		    // Find least recently used and not busy connection in cache
		    while ( iterator.hasNext() ) {
			Connection c = (Connection) iterator.next();
			if ( !c.isBusy() && c.getTimeStamp() < lru ) {
			    toClose = c; 
			    lru = c.getTimeStamp();
			}
		    }
		    
		    if ( toClose == null ) {
			return false;
		    }
		    
		    try {
			if (orb.transportDebugFlag) {
			    dprint(".reclaim: closing: " + toClose);
			}
			toClose.close();
		    } catch (Exception ex) {
			// REVISIT - log
		    }
		}

		if (orb.transportDebugFlag) {
		    dprint(".reclaim: connections reclaimed (" 
			    + (numberOfConnections - numberOfConnections()) + ")");
		}
	    }

	    // XXX is necessary to do a GC to reclaim
	    // closed network connections ??
	    // java.lang.System.gc();

	    return true;
	} finally {
	    if (orb.transportDebugFlag) {
		dprint(".reclaim<-: " + numberOfConnections());
	    }
	}
    
protected abstract voidregisterWithMonitoring()

public synchronized voidstampTime(com.sun.corba.se.pept.transport.Connection c)

	// _REVISIT_ Need to worry about wrap around some day
        c.setTimeStamp(timestamp++);
    
public abstract java.util.Collectionvalues()