Methods Summary |
---|
protected void | createPrimaryIndicator(org.apache.catalina.connector.Request request)Mark Request that processed at primary node with attribute
primaryIndicatorName
String id = request.getRequestedSessionId();
if ((id != null) && (id.length() > 0)) {
Manager manager = request.getContext().getManager();
Session session = manager.findSession(id);
if (session instanceof ClusterSession) {
ClusterSession cses = (ClusterSession) session;
if (cses != null) {
if (log.isDebugEnabled())
log.debug(sm.getString(
"ReplicationValve.session.indicator", request.getContext().getName(),id,
primaryIndicatorName, cses.isPrimarySession()));
request.setAttribute(primaryIndicatorName, cses.isPrimarySession()?Boolean.TRUE:Boolean.FALSE);
}
} else {
if (log.isDebugEnabled()) {
if (session != null) {
log.debug(sm.getString(
"ReplicationValve.session.found", request.getContext().getName(),id));
} else {
log.debug(sm.getString(
"ReplicationValve.session.invalid", request.getContext().getName(),id));
}
}
}
}
|
public boolean | doStatistics()Calc processing stats
return doProcessingStats;
|
public org.apache.catalina.ha.CatalinaCluster | getCluster()
return cluster;
|
public java.lang.String | getFilter()
return filter ;
|
public java.lang.String | getInfo()Return descriptive information about this Valve implementation.
return (info);
|
public long | getLastSendTime()
return lastSendTime;
|
public long | getNrOfCrossContextSendRequests()
return nrOfCrossContextSendRequests;
|
public long | getNrOfFilterRequests()
return nrOfFilterRequests;
|
public long | getNrOfRequests()
return nrOfRequests;
|
public long | getNrOfSendRequests()
return nrOfSendRequests;
|
public java.lang.String | getPrimaryIndicatorName()
return primaryIndicatorName;
|
protected java.util.regex.Pattern[] | getReqFilters()
return reqFilters;
|
public long | getTotalRequestTime()
return totalRequestTime;
|
public long | getTotalSendTime()
return totalSendTime;
|
public void | invoke(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response)Log the interesting request parameters, invoke the next Valve in the
sequence, and log the interesting response parameters.
long totalstart = 0;
//this happens before the request
if(doStatistics()) {
totalstart = System.currentTimeMillis();
}
if (primaryIndicator) {
createPrimaryIndicator(request) ;
}
Context context = request.getContext();
boolean isCrossContext = context != null
&& context instanceof StandardContext
&& ((StandardContext) context).getCrossContext();
try {
if(isCrossContext) {
if(log.isDebugEnabled())
log.debug(sm.getString("ReplicationValve.crossContext.add"));
//FIXME add Pool of Arraylists
crossContextSessions.set(new ArrayList());
}
getNext().invoke(request, response);
Manager manager = request.getContext().getManager();
if (manager != null && manager instanceof ClusterManager) {
ClusterManager clusterManager = (ClusterManager) manager;
CatalinaCluster containerCluster = (CatalinaCluster) getContainer().getCluster();
if (containerCluster == null) {
if (log.isWarnEnabled())
log.warn(sm.getString("ReplicationValve.nocluster"));
return;
}
// valve cluster can access manager - other cluster handle replication
// at host level - hopefully!
if(containerCluster.getManager(clusterManager.getName()) == null)
return ;
if(containerCluster.hasMembers()) {
sendReplicationMessage(request, totalstart, isCrossContext, clusterManager, containerCluster);
} else {
resetReplicationRequest(request,isCrossContext);
}
}
} finally {
// Array must be remove: Current master request send endAccess at recycle.
// Don't register this request session again!
if(isCrossContext) {
if(log.isDebugEnabled())
log.debug(sm.getString("ReplicationValve.crossContext.remove"));
// crossContextSessions.remove() only exist at Java 5
// register ArrayList at a pool
crossContextSessions.set(null);
}
}
|
public boolean | isPrimaryIndicator()
return primaryIndicator;
|
protected boolean | isRequestWithoutSessionChange(java.lang.String uri)is request without possible session change
boolean filterfound = false;
for (int i = 0; (i < reqFilters.length) && (!filterfound); i++) {
java.util.regex.Matcher matcher = reqFilters[i].matcher(uri);
filterfound = matcher.matches();
}
return filterfound;
|
public void | registerReplicationSession(org.apache.catalina.ha.session.DeltaSession session)Register all cross context sessions inside endAccess.
Use a list with contains check, that the Portlet API can include a lot of fragments from same or
different applications with session changes.
List sessions = (List)crossContextSessions.get();
if(sessions != null) {
if(!sessions.contains(session)) {
if(log.isDebugEnabled())
log.debug(sm.getString("ReplicationValve.crossContext.registerSession",
session.getIdInternal(),
session.getManager().getContainer().getName()));
sessions.add(session);
}
}
|
protected void | resetDeltaRequest(org.apache.catalina.Session session)Reset DeltaRequest from session
if(log.isDebugEnabled()) {
log.debug(sm.getString("ReplicationValve.resetDeltaRequest" ,
session.getManager().getContainer().getName() ));
}
((DeltaSession)session).resetDeltaRequest();
|
protected void | resetReplicationRequest(org.apache.catalina.connector.Request request, boolean isCrossContext)Fix memory leak for long sessions with many changes, when no backup member exists!
Session contextSession = request.getSessionInternal(false);
if(contextSession != null & contextSession instanceof DeltaSession){
resetDeltaRequest(contextSession);
((DeltaSession)contextSession).setPrimarySession(true);
}
if(isCrossContext) {
Object sessions = crossContextSessions.get();
if(sessions != null && sessions instanceof List
&& ((List)sessions).size() >0) {
Iterator iter = ((List)sessions).iterator();
for(; iter.hasNext() ;) {
Session session = (Session)iter.next();
resetDeltaRequest(session);
if(session instanceof DeltaSession)
((DeltaSession)contextSession).setPrimarySession(true);
}
}
}
|
public void | resetStatistics()reset the active statitics
totalRequestTime = 0 ;
totalSendTime = 0 ;
lastSendTime = 0 ;
nrOfFilterRequests = 0 ;
nrOfRequests = 0 ;
nrOfSendRequests = 0;
nrOfCrossContextSendRequests = 0;
|
protected void | send(org.apache.catalina.ha.ClusterManager manager, org.apache.catalina.ha.CatalinaCluster cluster, java.lang.String sessionId)send manager requestCompleted message to cluster
ClusterMessage msg = manager.requestCompleted(sessionId);
if (msg != null) {
if(manager.doDomainReplication()) {
cluster.sendClusterDomain(msg);
} else {
cluster.send(msg);
}
if(doStatistics())
nrOfSendRequests++;
}
|
protected void | sendCrossContextSession(org.apache.catalina.ha.CatalinaCluster containerCluster)Send all changed cross context sessions to backups
Object sessions = crossContextSessions.get();
if(sessions != null && sessions instanceof List
&& ((List)sessions).size() >0) {
for(Iterator iter = ((List)sessions).iterator(); iter.hasNext() ;) {
Session session = (Session)iter.next();
if(log.isDebugEnabled())
log.debug(sm.getString("ReplicationValve.crossContext.sendDelta",
session.getManager().getContainer().getName() ));
sendMessage(session,(ClusterManager)session.getManager(),containerCluster);
if(doStatistics()) {
nrOfCrossContextSendRequests++;
}
}
}
|
protected void | sendInvalidSessions(org.apache.catalina.ha.ClusterManager manager, org.apache.catalina.ha.CatalinaCluster cluster)check for session invalidations
String[] invalidIds=manager.getInvalidatedSessions();
if ( invalidIds.length > 0 ) {
for ( int i=0;i<invalidIds.length; i++ ) {
try {
send(manager,cluster,invalidIds[i]);
} catch ( Exception x ) {
log.error(sm.getString("ReplicationValve.send.invalid.failure",invalidIds[i]),x);
}
}
}
|
protected void | sendMessage(org.apache.catalina.Session session, org.apache.catalina.ha.ClusterManager manager, org.apache.catalina.ha.CatalinaCluster cluster)Send message delta message from request session
String id = session.getIdInternal();
if (id != null) {
send(manager, cluster, id);
}
|
protected void | sendReplicationMessage(org.apache.catalina.connector.Request request, long totalstart, boolean isCrossContext, org.apache.catalina.ha.ClusterManager clusterManager, org.apache.catalina.ha.CatalinaCluster containerCluster)
//this happens after the request
long start = 0;
if(doStatistics()) {
start = System.currentTimeMillis();
}
try {
// send invalid sessions
// DeltaManager returns String[0]
if (!(clusterManager instanceof DeltaManager))
sendInvalidSessions(clusterManager, containerCluster);
// send replication
sendSessionReplicationMessage(request, clusterManager, containerCluster);
if(isCrossContext)
sendCrossContextSession(containerCluster);
} catch (Exception x) {
// FIXME we have a lot of sends, but the trouble with one node stops the correct replication to other nodes!
log.error(sm.getString("ReplicationValve.send.failure"), x);
} finally {
// FIXME this stats update are not cheap!!
if(doStatistics()) {
updateStats(totalstart,start);
}
}
|
protected void | sendSessionReplicationMessage(org.apache.catalina.connector.Request request, org.apache.catalina.ha.ClusterManager manager, org.apache.catalina.ha.CatalinaCluster cluster)Send Cluster Replication Request
Session session = request.getSessionInternal(false);
if (session != null) {
String uri = request.getDecodedRequestURI();
// request without session change
if (!isRequestWithoutSessionChange(uri)) {
if (log.isDebugEnabled())
log.debug(sm.getString("ReplicationValve.invoke.uri", uri));
sendMessage(session,manager,cluster);
} else
if(doStatistics())
nrOfFilterRequests++;
}
|
public void | setCluster(org.apache.catalina.ha.CatalinaCluster cluster)
this.cluster = cluster;
|
public void | setFilter(java.lang.String filter)compile filter string to regular expressions
if (log.isDebugEnabled())
log.debug(sm.getString("ReplicationValve.filter.loading", filter));
this.filter = filter;
StringTokenizer t = new StringTokenizer(filter, ";");
this.reqFilters = new Pattern[t.countTokens()];
int i = 0;
while (t.hasMoreTokens()) {
String s = t.nextToken();
if (log.isTraceEnabled())
log.trace(sm.getString("ReplicationValve.filter.token", s));
try {
reqFilters[i++] = Pattern.compile(s);
} catch (Exception x) {
log.error(sm.getString("ReplicationValve.filter.token.failure",
s), x);
}
}
|
public void | setPrimaryIndicator(boolean primaryIndicator)
this.primaryIndicator = primaryIndicator;
|
public void | setPrimaryIndicatorName(java.lang.String primaryIndicatorName)
this.primaryIndicatorName = primaryIndicatorName;
|
protected void | setReqFilters(java.util.regex.Pattern[] reqFilters)
this.reqFilters = reqFilters;
|
public void | setStatistics(boolean doProcessingStats)Set Calc processing stats
this.doProcessingStats = doProcessingStats;
|
public java.lang.String | toString()Return a String rendering of this object.
StringBuffer sb = new StringBuffer("ReplicationValve[");
if (container != null)
sb.append(container.getName());
sb.append("]");
return (sb.toString());
|
protected void | updateStats(long requestTime, long clusterTime)protocol cluster replications stats
synchronized(this) {
lastSendTime=System.currentTimeMillis();
totalSendTime+=lastSendTime - clusterTime;
totalRequestTime+=lastSendTime - requestTime;
nrOfRequests++;
}
if(log.isInfoEnabled()) {
if ( (nrOfRequests % 100) == 0 ) {
log.info(sm.getString("ReplicationValve.stats",
new Object[]{
new Long(totalRequestTime/nrOfRequests),
new Long(totalSendTime/nrOfRequests),
new Long(nrOfRequests),
new Long(nrOfSendRequests),
new Long(nrOfCrossContextSendRequests),
new Long(nrOfFilterRequests),
new Long(totalRequestTime),
new Long(totalSendTime)}));
}
}
|