Author: pero
Date: Tue Dec 13 08:53:40 2005
New Revision: 356540
URL: http://svn.apache.org/viewcvs?rev=356540&view=rev
Log:
Optimized getMembers access from McastMembership
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/MembershipService.java
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastMembership.java
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastService.java
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastServiceImpl.java
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/ReplicationValve.java
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/SimpleTcpCluster.java
tomcat/container/tc5.5.x/modules/cluster/to-do.txt
tomcat/container/tc5.5.x/webapps/docs/changelog.xml
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/MembershipService.java
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/MembershipService.java?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
---
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/MembershipService.java
(original)
+++
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/MembershipService.java
Tue Dec 13 08:53:40 2005
@@ -62,10 +62,18 @@
* Stops the membership service
*/
public void stop();
+
+ /**
+ * Returns that cluster has members.
+ */
+ public boolean hasMembers();
+
/**
* Returns a list of all the members in the cluster.
*/
+
public Member[] getMembers();
+
/**
* Returns the member object that defines this member
*/
@@ -85,12 +93,14 @@
* Sets the local member properties for broadcasting
*/
public void setLocalMemberProperties(String listenHost, int listenPort);
+
/**
* Sets the membership listener, only one listener can be added.
* If you call this method twice, the last listener will be used.
* @param listener The listener
*/
public void addMembershipListener(MembershipListener listener);
+
/**
* removes the membership listener.
*/
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastMembership.java
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastMembership.java?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
---
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastMembership.java
(original)
+++
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastMembership.java
Tue Dec 13 08:53:40 2005
@@ -18,6 +18,11 @@
import java.util.HashMap;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
/**
* A <b>membership</b> implementation using simple multicast.
* This is the representation of a multicast membership.
@@ -25,28 +30,40 @@
* If a node fails to send out a heartbeat, the node will be dismissed.
*
* @author Filip Hanik
+ * @author Peter Rossbach
* @version $Revision$, $Date$
*/
-
-
public class McastMembership
{
+ protected static final McastMember[] EMPTY_MEMBERS = new McastMember[0];
+
/**
* The name of this membership, has to be the same as the name for the
local
* member
*/
protected String name;
+
/**
* A map of all the members in the cluster.
*/
- protected HashMap map = new java.util.HashMap();
+ protected Map map = new HashMap();
+
+ /**
+ * A list of all the members in the cluster.
+ */
+ protected McastMember[] members = EMPTY_MEMBERS;
+
+ /**
+ * sort members by alive time
+ */
+ protected MemberComparator memberComparator = new MemberComparator();
/**
* Constructs a new membership
- * @param myName - has to be the name of the local member. Used to filter
the local member from the cluster membership
+ * @param name - has to be the name of the local member. Used to filter
the local member from the cluster membership
*/
- public McastMembership(String myName) {
- name = myName;
+ public McastMembership(String name) {
+ this.name = name;
}
/**
@@ -55,35 +72,85 @@
*/
public synchronized void reset() {
map.clear();
+ members = EMPTY_MEMBERS ;
}
/**
* Notify the membership that this member has announced itself.
*
- * @param m - the member that just pinged us
+ * @param member - the member that just pinged us
* @return - true if this member is new to the cluster, false otherwise.
- * @return - false if this member is the local member.
+ * @return - false if this member is the local member or updated.
*/
- public synchronized boolean memberAlive(McastMember m) {
+ public synchronized boolean memberAlive(McastMember member) {
boolean result = false;
//ignore ourselves
- if ( m.getName().equals(name) ) return result;
+ if ( member.getName().equals(name) ) return result;
//return true if the membership has changed
- MbrEntry entry = (MbrEntry)map.get(m.getName());
+ MbrEntry entry = (MbrEntry)map.get(member.getName());
if ( entry == null ) {
- entry = new MbrEntry(m);
- map.put(m.getName(),entry);
+ entry = new MbrEntry(member);
+ map.put(member.getName(),entry);
+ addMcastMember(member);
result = true;
- } else {
+ } else {
//update the member alive time
- entry.getMember().setMemberAliveTime(m.getMemberAliveTime());
- }//end if
+ McastMember updateMember = entry.getMember() ;
+ if(updateMember.getMemberAliveTime() !=
member.getMemberAliveTime()) {
+ updateMember.setMemberAliveTime(member.getMemberAliveTime());
+ Arrays.sort(members, memberComparator);
+ }
+ }
entry.accessed();
+
return result;
}
/**
+ * Add a member to this component and sort array with memberComparator
+ * @param member The member to add
+ */
+ protected void addMcastMember(McastMember member) {
+ synchronized (members) {
+ McastMember results[] =
+ new McastMember[members.length + 1];
+ for (int i = 0; i < members.length; i++)
+ results[i] = members[i];
+ results[members.length] = member;
+ members = results;
+ Arrays.sort(members, memberComparator);
+ }
+ }
+
+ /**
+ * Remove a member from this component.
+ *
+ * @param member The member to remove
+ */
+ protected void removeMcastMember(McastMember member) {
+ synchronized (members) {
+ int n = -1;
+ for (int i = 0; i < members.length; i++) {
+ if (members[i] == member) {
+ n = i;
+ break;
+ }
+ }
+ if (n < 0)
+ return;
+ McastMember results[] =
+ new McastMember[members.length - 1];
+ int j = 0;
+ for (int i = 0; i < members.length; i++) {
+ if (i != n)
+ results[j++] = members[i];
+ }
+ members = results;
+ }
+ }
+
+ /**
* Runs a refresh cycle and returns a list of members that has expired.
* This also removes the members from the membership, in such a way that
* getMembers() = getMembers() - expire()
@@ -91,33 +158,55 @@
* @return the list of expired members
*/
public synchronized McastMember[] expire(long maxtime) {
- MbrEntry[] members = getMemberEntries();
- java.util.ArrayList list = new java.util.ArrayList();
- for (int i=0; i<members.length; i++) {
- MbrEntry entry = members[i];
- if ( entry.hasExpired(maxtime) ) {
+ if(!hasMembers() )
+ return EMPTY_MEMBERS;
+
+ ArrayList list = null;
+ Iterator i = map.values().iterator();
+ while(i.hasNext()) {
+ MbrEntry entry = (MbrEntry)i.next();
+ if( entry.hasExpired(maxtime) ) {
+ if(list == null) // only need a list when members are expired
(smaller gc)
+ list = new java.util.ArrayList();
list.add(entry.getMember());
- }//end if
- }//while
- McastMember[] result = new McastMember[list.size()];
- list.toArray(result);
- for ( int j=0; j<result.length; j++) map.remove(result[j].getName());
- return result;
-
- }//expire
+ }
+ }
+
+ if(list != null) {
+ McastMember[] result = new McastMember[list.size()];
+ list.toArray(result);
+ for( int j=0; j<result.length; j++) {
+ map.remove(result[j].getName());
+ removeMcastMember(result[j]);
+ }
+ return result;
+ } else {
+ return EMPTY_MEMBERS ;
+ }
+ }
/**
+ * Returning that service has members or not
+ */
+ public synchronized boolean hasMembers() {
+ return members.length > 0 ;
+ }
+
+ /**
* Returning a list of all the members in the membership
+ * We not need a copy: add and remove generate new arrays.
*/
public synchronized McastMember[] getMembers() {
- McastMember[] result = new McastMember[map.size()];
- java.util.Iterator i = map.entrySet().iterator();
- int pos = 0;
- while ( i.hasNext() )
- result[pos++] =
((MbrEntry)((java.util.Map.Entry)i.next()).getValue()).getMember();
- return result;
+ if(hasMembers()) {
+ return members;
+ } else {
+ return EMPTY_MEMBERS;
+ }
}
+ /**
+ * get a copy from all member entries
+ */
protected synchronized MbrEntry[] getMemberEntries()
{
MbrEntry[] result = new MbrEntry[map.size()];
@@ -127,8 +216,31 @@
result[pos++] =
((MbrEntry)((java.util.Map.Entry)i.next()).getValue());
return result;
}
+
+ // --------------------------------------------- Inner Class
+ private class MemberComparator implements java.util.Comparator {
+ public int compare(Object o1, Object o2) {
+ try {
+ return compare((McastMember) o1, (McastMember) o2);
+ } catch (ClassCastException x) {
+ return 0;
+ }
+ }
+
+ public int compare(McastMember m1, McastMember m2) {
+ //longer alive time, means sort first
+ long result = m2.getMemberAliveTime() - m1.getMemberAliveTime();
+ if (result < 0)
+ return -1;
+ else if (result == 0)
+ return 0;
+ else
+ return 1;
+ }
+ }
+
/**
* Inner class that represents a member entry
*/
@@ -137,15 +249,18 @@
protected McastMember mbr;
protected long lastHeardFrom;
+
public MbrEntry(McastMember mbr) {
- this.mbr = mbr;
+ this.mbr = mbr;
}
+
/**
* Indicate that this member has been accessed.
*/
public void accessed(){
- lastHeardFrom = System.currentTimeMillis();
+ lastHeardFrom = System.currentTimeMillis();
}
+
/**
* Return the actual McastMember object
*/
@@ -161,5 +276,5 @@
long delta = System.currentTimeMillis() - lastHeardFrom;
return delta > maxtime;
}
- }//MbrEntry
+ }
}
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastService.java
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastService.java?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
---
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastService.java
(original)
+++
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastService.java
Tue Dec 13 08:53:40 2005
@@ -58,7 +58,7 @@
/**
* The descriptive information about this implementation.
*/
- private static final String info = "McastService/2.0";
+ private static final String info = "McastService/2.1";
/**
* The implementation specific properties
@@ -419,7 +419,15 @@
}
return null;
}
-
+
+ /**
+ * has members?
+ */
+ public boolean hasMembers() {
+ if ( impl == null || impl.membership == null ) return false;
+ return impl.membership.hasMembers();
+ }
+
/**
* Return all the members
*/
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastServiceImpl.java
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastServiceImpl.java?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
---
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastServiceImpl.java
(original)
+++
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/mcast/McastServiceImpl.java
Tue Dec 13 08:53:40 2005
@@ -16,6 +16,13 @@
package org.apache.catalina.cluster.mcast;
+
+import java.net.MulticastSocket;
+import java.io.IOException;
+import java.net.InetAddress ;
+import java.net.DatagramPacket;
+import org.apache.catalina.cluster.MembershipListener;
+
/**
* A <b>membership</b> implementation using simple multicast.
* This is the representation of a multicast membership service.
@@ -27,12 +34,6 @@
* @author Filip Hanik
* @version $Revision$, $Date$
*/
-
-import java.net.MulticastSocket;
-import java.io.IOException;
-import java.net.InetAddress ;
-import java.net.DatagramPacket;
-import org.apache.catalina.cluster.MembershipListener;
public class McastServiceImpl
{
private static org.apache.commons.logging.Log log =
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/ReplicationValve.java
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/ReplicationValve.java?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
---
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/ReplicationValve.java
(original)
+++
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/ReplicationValve.java
Tue Dec 13 08:53:40 2005
@@ -243,32 +243,32 @@
long totalstart = System.currentTimeMillis();
//this happens before the request
if (primaryIndicator)
- createPrimaryIndicator( request) ;
+ createPrimaryIndicator(request) ;
getNext().invoke(request, response);
//this happens after the request
long start = System.currentTimeMillis();
Manager manager = request.getContext().getManager();
if (manager != null && manager instanceof ClusterManager) {
ClusterManager clusterManager = (ClusterManager) manager;
- CatalinaCluster cluster = (CatalinaCluster) getContainer()
+ CatalinaCluster containerCluster = (CatalinaCluster) getContainer()
.getCluster();
- if (cluster == null) {
+ if (containerCluster == null) {
if (log.isWarnEnabled())
log.warn(sm.getString("ReplicationValve.nocluster"));
return;
}
- // valve cluster can access manager - other clusterhandle
replication
+ // valve cluster can access manager - other cluster handle
replication
// at host level - hopefully!
- if(cluster.getManager(clusterManager.getName()) == null)
+ if(containerCluster.getManager(clusterManager.getName()) == null)
return ;
- if(cluster.getMembers().length > 0 ) {
+ if(containerCluster.getMembers().length > 0 ) {
try {
// send invalid sessions
// DeltaManager returns String[0]
if (!(clusterManager instanceof DeltaManager))
- sendInvalidSessions(clusterManager, cluster);
+ sendInvalidSessions(clusterManager, containerCluster);
// send replication
- sendSessionReplicationMessage(request, clusterManager,
cluster);
+ sendSessionReplicationMessage(request, clusterManager,
containerCluster);
} catch (Exception x) {
log.error(sm.getString("ReplicationValve.send.failure"),
x);
} finally {
Modified:
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/SimpleTcpCluster.java
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/SimpleTcpCluster.java?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
---
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/SimpleTcpCluster.java
(original)
+++
tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/tcp/SimpleTcpCluster.java
Tue Dec 13 08:53:40 2005
@@ -165,9 +165,6 @@
*/
protected Map managers = new HashMap();
- //sort members by alive time
- protected MemberComparator memberComparator = new MemberComparator();
-
private String managerClassName =
"org.apache.catalina.cluster.session.DeltaManager";
/**
@@ -395,27 +392,34 @@
}
}
+ /**
+ * get current Deployer
+ */
public org.apache.catalina.cluster.ClusterDeployer getClusterDeployer() {
return clusterDeployer;
}
+ /**
+ * set a new Deployer, must be set before cluster started!
+ */
public void setClusterDeployer(
org.apache.catalina.cluster.ClusterDeployer clusterDeployer) {
this.clusterDeployer = clusterDeployer;
}
/**
+ * has members
+ */
+ public boolean hasMembers() {
+ return membershipService.hasMembers();
+ }
+
+ /**
* Get all current cluster members
* @return all members or empty array
*/
public Member[] getMembers() {
- Member[] members = membershipService.getMembers();
- if(members != null) {
- //sort by alive time
- java.util.Arrays.sort(members, memberComparator);
- } else
- members = new Member[0];
- return members;
+ return membershipService.getMembers();
}
/**
@@ -1345,31 +1349,6 @@
public ObjectName getObjectName() {
return objectName;
}
-
- // --------------------------------------------- Inner Class
-
- private class MemberComparator implements java.util.Comparator {
-
- public int compare(Object o1, Object o2) {
- try {
- return compare((Member) o1, (Member) o2);
- } catch (ClassCastException x) {
- return 0;
- }
- }
-
- public int compare(Member m1, Member m2) {
- //longer alive time, means sort first
- long result = m2.getMemberAliveTime() - m1.getMemberAliveTime();
- if (result < 0)
- return -1;
- else if (result == 0)
- return 0;
- else
- return 1;
- }
- }
-
// ------------------------------------------------------------- deprecated
Modified: tomcat/container/tc5.5.x/modules/cluster/to-do.txt
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/modules/cluster/to-do.txt?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/modules/cluster/to-do.txt (original)
+++ tomcat/container/tc5.5.x/modules/cluster/to-do.txt Tue Dec 13 08:53:40 2005
@@ -1,7 +1,11 @@
==============================
Next actions
==============================
-
+- support CrossContext session replication
+ Idea: use endAccess to signal replicationValve that session from other app
has changed.
+ refactor ReplicationValve
+ When session is serialzed from other app, set right app classloader
+ endaccess is also send at CoyoteAdpater for context session as recycle the
request
- Add MbeanFactory to generate dynamic cluster at runtime.
Problem: How we can start those central services?
- StandardEngine support load Mbean from external file.
@@ -199,6 +203,11 @@
==============================
COMPLETED
==============================
+5.5.15 (pero)
+- Optimized getMembers access from McastMembership
+ Member list was copied at every access. (Used inside
ReplicationValve.invoke)
+ SimpleTcpCluster need a alive time sorted array
+
5.5.11 (pero)
- MemoryUser principal from UserDatabaseRealm not handled to replicated
- look inside DeltaRequest.setPrincipal(Principal,boolean)
Modified: tomcat/container/tc5.5.x/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/webapps/docs/changelog.xml?rev=356540&r1=356539&r2=356540&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/webapps/docs/changelog.xml (original)
+++ tomcat/container/tc5.5.x/webapps/docs/changelog.xml Tue Dec 13 08:53:40 2005
@@ -37,6 +37,9 @@
<add>
DataSender starts new Socket after IOException. (pero)
</add>
+ <update>
+ Reduce memory usage at membership service. (pero)
+ </update>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]