private ReplicationValve prepareClusterValve(Property clusterProp) { ReplicationValve clusterValve = new ReplicationValve(); String defaultValveFilter = ".*\\.gif;.*\\.js;.*\\.jpg;.*\\.htm;.*\\.html;.*\\.txt;.*\\.png;.*\\.css;.*\\.ico;.*\\.htc;"; clusterValve.setFilter(ContainerConfig.getPropertyValue(clusterProp, "rep-valve-filter", defaultValveFilter)); return clusterValve; }
protected void sendReplicationMessage(Request request, long totalstart, boolean isCrossContext, ClusterManager clusterManager) { //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); } // send replication sendSessionReplicationMessage(request, clusterManager); if(isCrossContext) { sendCrossContextSession(); } } 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); } } }
/** * Send Cluster Replication Request * @param request current request * @param manager session manager * @param cluster replication cluster */ protected void sendSessionReplicationMessage(Request request, ClusterManager manager, CatalinaCluster cluster) { 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++; } }
if(doStatistics()) { totalstart = System.currentTimeMillis(); createPrimaryIndicator(request) ; getNext().invoke(request, response); if(context != null && cluster != null && context.getManager() instanceof ClusterManager) { sendReplicationMessage(request, totalstart, isCrossContext, clusterManager); } else { resetReplicationRequest(request,isCrossContext);
/** * Send all changed cross context sessions to backups * @param containerCluster */ protected void sendCrossContextSession(CatalinaCluster containerCluster) { List<DeltaSession> sessions = crossContextSessions.get(); if(sessions != null && sessions.size() >0) { for(Iterator<DeltaSession> iter = sessions.iterator(); iter.hasNext() ;) { 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++; } } } }
/** * Send message delta message from request session * @param session current session * @param manager session manager */ protected void sendMessage(Session session, ClusterManager manager) { String id = session.getIdInternal(); if (id != null) { send(manager, id); } }
/** * Start this component and implement the requirements * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ @Override protected synchronized void startInternal() throws LifecycleException { if (cluster == null) { Cluster containerCluster = getContainer().getCluster(); if (containerCluster instanceof CatalinaCluster) { setCluster((CatalinaCluster)containerCluster); } else { if (log.isWarnEnabled()) { log.warn(sm.getString("ReplicationValve.nocluster")); } } } super.startInternal(); }
protected void checkDefaults() { if ( clusterListeners.size() == 0 ) { addClusterListener(new ClusterSessionListener()); } if ( valves.size() == 0 ) { addValve(new JvmRouteBinderValve()); addValve(new ReplicationValve()); } if ( clusterDeployer != null ) clusterDeployer.setCluster(this); if ( channel == null ) channel = new GroupChannel(); if ( channel instanceof GroupChannel && !((GroupChannel)channel).getInterceptors().hasNext()) { channel.addInterceptor(new MessageDispatch15Interceptor()); channel.addInterceptor(new TcpFailureDetector()); } }
/** * send manager requestCompleted message to cluster * @param manager SessionManager * @param sessionId sessionid from the manager * @see DeltaManager#requestCompleted(String) * @see SimpleTcpCluster#send(ClusterMessage) */ protected void send(ClusterManager manager, String sessionId) { ClusterMessage msg = manager.requestCompleted(sessionId); if (msg != null && cluster != null) { cluster.send(msg); if(doStatistics()) { nrOfSendRequests++; } } }
/** * Register cross context session at replication valve thread local * @param session cross context session */ protected void registerSessionAtReplicationValve(DeltaSession session) { if(replicationValve == null) { CatalinaCluster cluster = getCluster() ; if(cluster != null) { Valve[] valves = cluster.getValves(); if(valves != null && valves.length > 0) { for(int i=0; replicationValve == null && i < valves.length ; i++ ){ if(valves[i] instanceof ReplicationValve) replicationValve = (ReplicationValve)valves[i] ; }//for if(replicationValve == null && log.isDebugEnabled()) { log.debug("no ReplicationValve found for CrossContext Support"); }//endif }//end if }//endif }//end if if(replicationValve != null) { replicationValve.registerReplicationSession(session); } }
/** * Fix memory leak for long sessions with many changes, when no backup member exists! * @param request current request after response is generated * @param isCrossContext check crosscontext threadlocal */ protected void resetReplicationRequest(Request request, boolean isCrossContext) { Session contextSession = request.getSessionInternal(false); if(contextSession instanceof DeltaSession){ resetDeltaRequest(contextSession); ((DeltaSession)contextSession).setPrimarySession(true); } if(isCrossContext) { List<DeltaSession> sessions = crossContextSessions.get(); if(sessions != null && sessions.size() >0) { Iterator<DeltaSession> iter = sessions.iterator(); for(; iter.hasNext() ;) { Session session = iter.next(); resetDeltaRequest(session); if(session instanceof DeltaSession) ((DeltaSession)contextSession).setPrimarySession(true); } } } }
if(doStatistics()) { totalstart = System.currentTimeMillis(); createPrimaryIndicator(request) ; getNext().invoke(request, response); if(context != null && cluster != null && context.getManager() instanceof ClusterManager) { sendReplicationMessage(request, totalstart, isCrossContext, clusterManager); } else { resetReplicationRequest(request,isCrossContext);
/** * Send all changed cross context sessions to backups */ protected void sendCrossContextSession() { List<DeltaSession> sessions = crossContextSessions.get(); if(sessions != null && sessions.size() >0) { for(Iterator<DeltaSession> iter = sessions.iterator(); iter.hasNext() ;) { Session session = iter.next(); if(log.isDebugEnabled()) { log.debug(sm.getString("ReplicationValve.crossContext.sendDelta", session.getManager().getContext().getName() )); } sendMessage(session,(ClusterManager)session.getManager()); if(doStatistics()) { nrOfCrossContextSendRequests++; } } } }
/** * Send message delta message from request session * @param session current session * @param manager session manager */ protected void sendMessage(Session session, ClusterManager manager) { String id = session.getIdInternal(); if (id != null) { send(manager, id); } }
/** * Start this component and implement the requirements * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ @Override protected synchronized void startInternal() throws LifecycleException { if (cluster == null) { Cluster containerCluster = getContainer().getCluster(); if (containerCluster instanceof CatalinaCluster) { setCluster((CatalinaCluster)containerCluster); } else { if (log.isWarnEnabled()) { log.warn(sm.getString("ReplicationValve.nocluster")); } } } super.startInternal(); }
protected void checkDefaults() { if ( clusterListeners.size() == 0 && managerTemplate instanceof DeltaManager ) { addClusterListener(new ClusterSessionListener()); } if ( valves.size() == 0 ) { addValve(new JvmRouteBinderValve()); addValve(new ReplicationValve()); } if ( clusterDeployer != null ) clusterDeployer.setCluster(this); if ( channel == null ) channel = new GroupChannel(); if ( channel instanceof GroupChannel && !((GroupChannel)channel).getInterceptors().hasNext()) { channel.addInterceptor(new MessageDispatchInterceptor()); channel.addInterceptor(new TcpFailureDetector()); } if (heartbeatBackgroundEnabled) channel.setHeartbeat(false); }
/** * send manager requestCompleted message to cluster * @param manager SessionManager * @param sessionId sessionid from the manager * @see DeltaManager#requestCompleted(String) * @see SimpleTcpCluster#send(ClusterMessage) */ protected void send(ClusterManager manager, String sessionId) { ClusterMessage msg = manager.requestCompleted(sessionId); if (msg != null && cluster != null) { cluster.send(msg); if(doStatistics()) { nrOfSendRequests++; } } }
/** * Register cross context session at replication valve thread local * @param session cross context session */ protected void registerSessionAtReplicationValve(DeltaSession session) { if(replicationValve == null) { if(container instanceof StandardContext && ((StandardContext)container).getCrossContext()) { CatalinaCluster cluster = getCluster() ; if(cluster != null) { Valve[] valves = cluster.getValves(); if(valves != null && valves.length > 0) { for(int i=0; replicationValve == null && i < valves.length ; i++ ){ if(valves[i] instanceof ReplicationValve) replicationValve = (ReplicationValve)valves[i] ; }//for if(replicationValve == null && log.isDebugEnabled()) { log.debug("no ReplicationValve found for CrossContext Support"); }//endif }//end if }//endif }//end if }//end if if(replicationValve != null) { replicationValve.registerReplicationSession(session); } }
/** * Fix memory leak for long sessions with many changes, when no backup member exists! * @param request current request after response is generated * @param isCrossContext check crosscontext threadlocal */ protected void resetReplicationRequest(Request request, boolean isCrossContext) { Session contextSession = request.getSessionInternal(false); if(contextSession instanceof DeltaSession){ resetDeltaRequest(contextSession); ((DeltaSession)contextSession).setPrimarySession(true); } if(isCrossContext) { List<DeltaSession> sessions = crossContextSessions.get(); if(sessions != null && sessions.size() >0) { Iterator<DeltaSession> iter = sessions.iterator(); for(; iter.hasNext() ;) { Session session = iter.next(); resetDeltaRequest(session); if(session instanceof DeltaSession) { ((DeltaSession)contextSession).setPrimarySession(true); } } } } }
if(doStatistics()) { totalstart = System.currentTimeMillis(); createPrimaryIndicator(request) ; getNext().invoke(request, response); if(context != null) { Manager manager = context.getManager(); if (manager != null && manager instanceof ClusterManager) { ClusterManager clusterManager = (ClusterManager) manager; CatalinaCluster containerCluster = (CatalinaCluster) getContainer().getCluster(); if (containerCluster == null) { if (log.isWarnEnabled()) return ; if(containerCluster.hasMembers()) { sendReplicationMessage(request, totalstart, isCrossContext, clusterManager, containerCluster); } else { resetReplicationRequest(request,isCrossContext);