You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2006/10/24 05:18:02 UTC
svn commit: r467222 [22/31] - in /tomcat/tc6.0.x/trunk/java:
javax/annotation/ javax/annotation/security/ javax/ejb/ javax/el/
javax/mail/ javax/mail/internet/ javax/persistence/ javax/servlet/
javax/servlet/http/ javax/servlet/jsp/ javax/servlet/jsp/e...
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/MemberImpl.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/MemberImpl.java?view=diff&rev=467222&r1=467221&r2=467222
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/MemberImpl.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/MemberImpl.java Mon Oct 23 20:17:11 2006
@@ -1,597 +1,597 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.catalina.tribes.membership;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.Arrays;
-
-import org.apache.catalina.tribes.Member;
-import org.apache.catalina.tribes.io.XByteBuffer;
-import org.apache.catalina.tribes.transport.SenderState;
-
-/**
- * A <b>membership</b> implementation using simple multicast.
- * This is the representation of a multicast member.
- * Carries the host, and port of the this or other cluster nodes.
- *
- * @author Filip Hanik
- * @version $Revision: 304032 $, $Date: 2005-07-27 10:11:55 -0500 (Wed, 27 Jul 2005) $
- */
-public class MemberImpl implements Member, java.io.Externalizable {
-
- /**
- * Public properties specific to this implementation
- */
- public static final transient String TCP_LISTEN_PORT = "tcpListenPort";
- public static final transient String TCP_LISTEN_HOST = "tcpListenHost";
- public static final transient String MEMBER_NAME = "memberName";
-
- public static final transient byte[] TRIBES_MBR_BEGIN = new byte[] {84, 82, 73, 66, 69, 83, 45, 66};
- public static final transient byte[] TRIBES_MBR_END = new byte[] {84, 82, 73, 66, 69, 83, 45, 69};
-
- /**
- * The listen host for this member
- */
- protected byte[] host;
- protected transient String hostname;
- /**
- * The tcp listen port for this member
- */
- protected int port;
-
- /**
- * The tcp/SSL listen port for this member
- */
- protected int securePort = -1;
-
- /**
- * Counter for how many broadcast messages have been sent from this member
- */
- protected int msgCount = 0;
- /**
- * The number of milliseconds since this members was
- * created, is kept track of using the start time
- */
- protected long memberAliveTime = 0;
-
- /**
- * For the local member only
- */
- protected transient long serviceStartTime;
-
- /**
- * To avoid serialization over and over again, once the local dataPkg
- * has been set, we use that to transmit data
- */
- protected transient byte[] dataPkg = null;
-
- /**
- * Unique session Id for this member
- */
- protected byte[] uniqueId = new byte[16];
-
- /**
- * Custom payload that an app framework can broadcast
- * Also used to transport stop command.
- */
- protected byte[] payload = new byte[0];
-
- /**
- * Command, so that the custom payload doesn't have to be used
- * This is for internal tribes use, such as SHUTDOWN_COMMAND
- */
- protected byte[] command = new byte[0];
-
- /**
- * Domain if we want to filter based on domain.
- */
- protected byte[] domain = new byte[0];
-
- /**
- * Empty constructor for serialization
- */
- public MemberImpl() {
-
- }
-
- /**
- * Construct a new member object
- * @param name - the name of this member, cluster unique
- * @param domain - the cluster domain name of this member
- * @param host - the tcp listen host
- * @param port - the tcp listen port
- */
- public MemberImpl(String host,
- int port,
- long aliveTime) throws IOException {
- setHostname(host);
- this.port = port;
- this.memberAliveTime=aliveTime;
- }
-
- public MemberImpl(String host,
- int port,
- long aliveTime,
- byte[] payload) throws IOException {
- this(host,port,aliveTime);
- setPayload(payload);
- }
-
- public boolean isReady() {
- return SenderState.getSenderState(this).isReady();
- }
- public boolean isSuspect() {
- return SenderState.getSenderState(this).isSuspect();
- }
- public boolean isFailing() {
- return SenderState.getSenderState(this).isFailing();
- }
-
- /**
- * Increment the message count.
- */
- protected void inc() {
- msgCount++;
- }
-
- /**
- * Create a data package to send over the wire representing this member.
- * This is faster than serialization.
- * @return - the bytes for this member deserialized
- * @throws Exception
- */
- public byte[] getData() {
- return getData(true);
- }
- /**
- * Highly optimized version of serializing a member into a byte array
- * Returns a cached byte[] reference, do not modify this data
- * @param getalive boolean
- * @return byte[]
- */
- public byte[] getData(boolean getalive) {
- return getData(getalive,false);
- }
-
-
- public int getDataLength() {
- return TRIBES_MBR_BEGIN.length+ //start pkg
- 4+ //data length
- 8+ //alive time
- 4+ //port
- 4+ //secure port
- 1+ //host length
- host.length+ //host
- 4+ //command length
- command.length+ //command
- 4+ //domain length
- domain.length+ //domain
- 16+ //unique id
- 4+ //payload length
- payload.length+ //payload
- TRIBES_MBR_END.length; //end pkg
- }
-
- /**
- *
- * @param getalive boolean - calculate memberAlive time
- * @param reset boolean - reset the cached data package, and create a new one
- * @return byte[]
- */
- public byte[] getData(boolean getalive, boolean reset) {
- if ( reset ) dataPkg = null;
- //look in cache first
- if ( dataPkg!=null ) {
- if ( getalive ) {
- //you'd be surprised, but System.currentTimeMillis
- //shows up on the profiler
- long alive=System.currentTimeMillis()-getServiceStartTime();
- XByteBuffer.toBytes( (long) alive, dataPkg, TRIBES_MBR_BEGIN.length+4);
- }
- return dataPkg;
- }
-
- //package looks like
- //start package TRIBES_MBR_BEGIN.length
- //package length - 4 bytes
- //alive - 8 bytes
- //port - 4 bytes
- //secure port - 4 bytes
- //host length - 1 byte
- //host - hl bytes
- //clen - 4 bytes
- //command - clen bytes
- //dlen - 4 bytes
- //domain - dlen bytes
- //uniqueId - 16 bytes
- //payload length - 4 bytes
- //payload plen bytes
- //end package TRIBES_MBR_END.length
- byte[] addr = host;
- long alive=System.currentTimeMillis()-getServiceStartTime();
- byte hl = (byte)addr.length;
- byte[] data = new byte[getDataLength()];
-
- int bodylength = (getDataLength() - TRIBES_MBR_BEGIN.length - TRIBES_MBR_END.length - 4);
-
- int pos = 0;
-
- //TRIBES_MBR_BEGIN
- System.arraycopy(TRIBES_MBR_BEGIN,0,data,pos,TRIBES_MBR_BEGIN.length);
- pos += TRIBES_MBR_BEGIN.length;
-
- //body length
- XByteBuffer.toBytes(bodylength,data,pos);
- pos += 4;
-
- //alive data
- XByteBuffer.toBytes((long)alive,data,pos);
- pos += 8;
- //port
- XByteBuffer.toBytes(port,data,pos);
- pos += 4;
- //secure port
- XByteBuffer.toBytes(securePort,data,pos);
- pos += 4;
- //host length
- data[pos++] = hl;
- //host
- System.arraycopy(addr,0,data,pos,addr.length);
- pos+=addr.length;
- //clen - 4 bytes
- XByteBuffer.toBytes(command.length,data,pos);
- pos+=4;
- //command - clen bytes
- System.arraycopy(command,0,data,pos,command.length);
- pos+=command.length;
- //dlen - 4 bytes
- XByteBuffer.toBytes(domain.length,data,pos);
- pos+=4;
- //domain - dlen bytes
- System.arraycopy(domain,0,data,pos,domain.length);
- pos+=domain.length;
- //unique Id
- System.arraycopy(uniqueId,0,data,pos,uniqueId.length);
- pos+=uniqueId.length;
- //payload
- XByteBuffer.toBytes(payload.length,data,pos);
- pos+=4;
- System.arraycopy(payload,0,data,pos,payload.length);
- pos+=payload.length;
-
- //TRIBES_MBR_END
- System.arraycopy(TRIBES_MBR_END,0,data,pos,TRIBES_MBR_END.length);
- pos += TRIBES_MBR_END.length;
-
- //create local data
- dataPkg = data;
- return data;
- }
- /**
- * Deserializes a member from data sent over the wire
- * @param data - the bytes received
- * @return a member object.
- */
- public static MemberImpl getMember(byte[] data, MemberImpl member) {
- return getMember(data,0,data.length,member);
- }
-
- public static MemberImpl getMember(byte[] data, int offset, int length, MemberImpl member) {
- //package looks like
- //start package TRIBES_MBR_BEGIN.length
- //package length - 4 bytes
- //alive - 8 bytes
- //port - 4 bytes
- //secure port - 4 bytes
- //host length - 1 byte
- //host - hl bytes
- //clen - 4 bytes
- //command - clen bytes
- //dlen - 4 bytes
- //domain - dlen bytes
- //uniqueId - 16 bytes
- //payload length - 4 bytes
- //payload plen bytes
- //end package TRIBES_MBR_END.length
-
- int pos = offset;
-
- if (XByteBuffer.firstIndexOf(data,offset,TRIBES_MBR_BEGIN)!=pos) {
- throw new IllegalArgumentException("Invalid package, should start with:"+org.apache.catalina.tribes.util.Arrays.toString(TRIBES_MBR_BEGIN));
- }
-
- if ( length < (TRIBES_MBR_BEGIN.length+4) ) {
- throw new ArrayIndexOutOfBoundsException("Member package to small to validate.");
- }
-
- pos += TRIBES_MBR_BEGIN.length;
-
- int bodylength = XByteBuffer.toInt(data,pos);
- pos += 4;
-
- if ( length < (bodylength+4+TRIBES_MBR_BEGIN.length+TRIBES_MBR_END.length) ) {
- throw new ArrayIndexOutOfBoundsException("Not enough bytes in member package.");
- }
-
- int endpos = pos+bodylength;
- if (XByteBuffer.firstIndexOf(data,endpos,TRIBES_MBR_END)!=endpos) {
- throw new IllegalArgumentException("Invalid package, should end with:"+org.apache.catalina.tribes.util.Arrays.toString(TRIBES_MBR_END));
- }
-
-
- byte[] alived = new byte[8];
- System.arraycopy(data, pos, alived, 0, 8);
- pos += 8;
- byte[] portd = new byte[4];
- System.arraycopy(data, pos, portd, 0, 4);
- pos += 4;
-
- byte[] sportd = new byte[4];
- System.arraycopy(data, pos, sportd, 0, 4);
- pos += 4;
-
-
-
- byte hl = data[pos++];
- byte[] addr = new byte[hl];
- System.arraycopy(data, pos, addr, 0, hl);
- pos += hl;
-
- int cl = XByteBuffer.toInt(data, pos);
- pos += 4;
-
- byte[] command = new byte[cl];
- System.arraycopy(data, pos, command, 0, command.length);
- pos += command.length;
-
- int dl = XByteBuffer.toInt(data, pos);
- pos += 4;
-
- byte[] domain = new byte[dl];
- System.arraycopy(data, pos, domain, 0, domain.length);
- pos += domain.length;
-
- byte[] uniqueId = new byte[16];
- System.arraycopy(data, pos, uniqueId, 0, 16);
- pos += 16;
-
- int pl = XByteBuffer.toInt(data, pos);
- pos += 4;
-
- byte[] payload = new byte[pl];
- System.arraycopy(data, pos, payload, 0, payload.length);
- pos += payload.length;
-
- member.setHost(addr);
- member.setPort(XByteBuffer.toInt(portd, 0));
- member.setSecurePort(XByteBuffer.toInt(sportd, 0));
- member.setMemberAliveTime(XByteBuffer.toLong(alived, 0));
- member.setUniqueId(uniqueId);
- member.payload = payload;
- member.domain = domain;
- member.command = command;
-
- member.dataPkg = new byte[length];
- System.arraycopy(data, offset, member.dataPkg, 0, length);
-
- return member;
- }
-
- public static MemberImpl getMember(byte[] data) {
- return getMember(data,new MemberImpl());
- }
-
- /**
- * Return the name of this object
- * @return a unique name to the cluster
- */
- public String getName() {
- return "tcp://"+getHostname()+":"+getPort();
- }
-
- /**
- * Return the listen port of this member
- * @return - tcp listen port
- */
- public int getPort() {
- return this.port;
- }
-
- /**
- * Return the TCP listen host for this member
- * @return IP address or host name
- */
- public byte[] getHost() {
- return host;
- }
-
- public String getHostname() {
- if ( this.hostname != null ) return hostname;
- else {
- try {
- this.hostname = java.net.InetAddress.getByAddress(host).getHostName();
- return this.hostname;
- }catch ( IOException x ) {
- throw new RuntimeException("Unable to parse hostname.",x);
- }
- }
- }
-
- /**
- * Contains information on how long this member has been online.
- * The result is the number of milli seconds this member has been
- * broadcasting its membership to the cluster.
- * @return nr of milliseconds since this member started.
- */
- public long getMemberAliveTime() {
- return memberAliveTime;
- }
-
- public long getServiceStartTime() {
- return serviceStartTime;
- }
-
- public byte[] getUniqueId() {
- return uniqueId;
- }
-
- public byte[] getPayload() {
- return payload;
- }
-
- public byte[] getCommand() {
- return command;
- }
-
- public byte[] getDomain() {
- return domain;
- }
-
- public int getSecurePort() {
- return securePort;
- }
-
- public void setMemberAliveTime(long time) {
- memberAliveTime=time;
- }
-
-
-
- /**
- * String representation of this object
- */
- public String toString() {
- StringBuffer buf = new StringBuffer("org.apache.catalina.tribes.membership.MemberImpl[");
- buf.append(getName()).append(",");
- buf.append(getHostname()).append(",");
- buf.append(port).append(", alive=");
- buf.append(memberAliveTime).append(",");
- buf.append("id=").append(bToS(this.uniqueId)).append(", ");
- buf.append("payload=").append(bToS(this.payload,8)).append(", ");
- buf.append("command=").append(bToS(this.command,8)).append(", ");
- buf.append("domain=").append(bToS(this.domain,8)).append(", ");
- buf.append("]");
- return buf.toString();
- }
- public static String bToS(byte[] data) {
- return bToS(data,data.length);
- }
- public static String bToS(byte[] data, int max) {
- StringBuffer buf = new StringBuffer(4*16);
- buf.append("{");
- for (int i=0; data!=null && i<data.length; i++ ) {
- buf.append(String.valueOf(data[i])).append(" ");
- if ( i==max ) {
- buf.append("...("+data.length+")");
- break;
- }
- }
- buf.append("}");
- return buf.toString();
- }
-
- /**
- * @see java.lang.Object#hashCode()
- * @return The hash code
- */
- public int hashCode() {
- return getHost()[0]+getHost()[1]+getHost()[2]+getHost()[3];
- }
-
- /**
- * Returns true if the param o is a McastMember with the same name
- * @param o
- */
- public boolean equals(Object o) {
- if ( o instanceof MemberImpl ) {
- return Arrays.equals(this.getHost(),((MemberImpl)o).getHost()) &&
- this.getPort() == ((MemberImpl)o).getPort() &&
- Arrays.equals(this.getUniqueId(),((MemberImpl)o).getUniqueId());
- }
- else
- return false;
- }
-
- public void setHost(byte[] host) {
- this.host = host;
- }
-
- public void setHostname(String host) throws IOException {
- hostname = host;
- this.host = java.net.InetAddress.getByName(host).getAddress();
- }
-
- public void setMsgCount(int msgCount) {
- this.msgCount = msgCount;
- }
-
- public void setPort(int port) {
- this.port = port;
- this.dataPkg = null;
- }
-
- public void setServiceStartTime(long serviceStartTime) {
- this.serviceStartTime = serviceStartTime;
- }
-
- public void setUniqueId(byte[] uniqueId) {
- this.uniqueId = uniqueId!=null?uniqueId:new byte[16];
- getData(true,true);
- }
-
- public void setPayload(byte[] payload) {
- byte[] oldpayload = this.payload;
- this.payload = payload!=null?payload:new byte[0];
- if ( this.getData(true,true).length > McastServiceImpl.MAX_PACKET_SIZE ) {
- this.payload = oldpayload;
- throw new IllegalArgumentException("Payload is to large for tribes to handle.");
- }
-
- }
-
- public void setCommand(byte[] command) {
- this.command = command!=null?command:new byte[0];
- getData(true,true);
- }
-
- public void setDomain(byte[] domain) {
- this.domain = domain!=null?domain:new byte[0];
- getData(true,true);
- }
-
- public void setSecurePort(int securePort) {
- this.securePort = securePort;
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- int length = in.readInt();
- byte[] message = new byte[length];
- in.read(message);
- getMember(message,this);
-
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- byte[] data = this.getData();
- out.writeInt(data.length);
- out.write(data);
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.tribes.membership;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+
+import org.apache.catalina.tribes.Member;
+import org.apache.catalina.tribes.io.XByteBuffer;
+import org.apache.catalina.tribes.transport.SenderState;
+
+/**
+ * A <b>membership</b> implementation using simple multicast.
+ * This is the representation of a multicast member.
+ * Carries the host, and port of the this or other cluster nodes.
+ *
+ * @author Filip Hanik
+ * @version $Revision$, $Date$
+ */
+public class MemberImpl implements Member, java.io.Externalizable {
+
+ /**
+ * Public properties specific to this implementation
+ */
+ public static final transient String TCP_LISTEN_PORT = "tcpListenPort";
+ public static final transient String TCP_LISTEN_HOST = "tcpListenHost";
+ public static final transient String MEMBER_NAME = "memberName";
+
+ public static final transient byte[] TRIBES_MBR_BEGIN = new byte[] {84, 82, 73, 66, 69, 83, 45, 66};
+ public static final transient byte[] TRIBES_MBR_END = new byte[] {84, 82, 73, 66, 69, 83, 45, 69};
+
+ /**
+ * The listen host for this member
+ */
+ protected byte[] host;
+ protected transient String hostname;
+ /**
+ * The tcp listen port for this member
+ */
+ protected int port;
+
+ /**
+ * The tcp/SSL listen port for this member
+ */
+ protected int securePort = -1;
+
+ /**
+ * Counter for how many broadcast messages have been sent from this member
+ */
+ protected int msgCount = 0;
+ /**
+ * The number of milliseconds since this members was
+ * created, is kept track of using the start time
+ */
+ protected long memberAliveTime = 0;
+
+ /**
+ * For the local member only
+ */
+ protected transient long serviceStartTime;
+
+ /**
+ * To avoid serialization over and over again, once the local dataPkg
+ * has been set, we use that to transmit data
+ */
+ protected transient byte[] dataPkg = null;
+
+ /**
+ * Unique session Id for this member
+ */
+ protected byte[] uniqueId = new byte[16];
+
+ /**
+ * Custom payload that an app framework can broadcast
+ * Also used to transport stop command.
+ */
+ protected byte[] payload = new byte[0];
+
+ /**
+ * Command, so that the custom payload doesn't have to be used
+ * This is for internal tribes use, such as SHUTDOWN_COMMAND
+ */
+ protected byte[] command = new byte[0];
+
+ /**
+ * Domain if we want to filter based on domain.
+ */
+ protected byte[] domain = new byte[0];
+
+ /**
+ * Empty constructor for serialization
+ */
+ public MemberImpl() {
+
+ }
+
+ /**
+ * Construct a new member object
+ * @param name - the name of this member, cluster unique
+ * @param domain - the cluster domain name of this member
+ * @param host - the tcp listen host
+ * @param port - the tcp listen port
+ */
+ public MemberImpl(String host,
+ int port,
+ long aliveTime) throws IOException {
+ setHostname(host);
+ this.port = port;
+ this.memberAliveTime=aliveTime;
+ }
+
+ public MemberImpl(String host,
+ int port,
+ long aliveTime,
+ byte[] payload) throws IOException {
+ this(host,port,aliveTime);
+ setPayload(payload);
+ }
+
+ public boolean isReady() {
+ return SenderState.getSenderState(this).isReady();
+ }
+ public boolean isSuspect() {
+ return SenderState.getSenderState(this).isSuspect();
+ }
+ public boolean isFailing() {
+ return SenderState.getSenderState(this).isFailing();
+ }
+
+ /**
+ * Increment the message count.
+ */
+ protected void inc() {
+ msgCount++;
+ }
+
+ /**
+ * Create a data package to send over the wire representing this member.
+ * This is faster than serialization.
+ * @return - the bytes for this member deserialized
+ * @throws Exception
+ */
+ public byte[] getData() {
+ return getData(true);
+ }
+ /**
+ * Highly optimized version of serializing a member into a byte array
+ * Returns a cached byte[] reference, do not modify this data
+ * @param getalive boolean
+ * @return byte[]
+ */
+ public byte[] getData(boolean getalive) {
+ return getData(getalive,false);
+ }
+
+
+ public int getDataLength() {
+ return TRIBES_MBR_BEGIN.length+ //start pkg
+ 4+ //data length
+ 8+ //alive time
+ 4+ //port
+ 4+ //secure port
+ 1+ //host length
+ host.length+ //host
+ 4+ //command length
+ command.length+ //command
+ 4+ //domain length
+ domain.length+ //domain
+ 16+ //unique id
+ 4+ //payload length
+ payload.length+ //payload
+ TRIBES_MBR_END.length; //end pkg
+ }
+
+ /**
+ *
+ * @param getalive boolean - calculate memberAlive time
+ * @param reset boolean - reset the cached data package, and create a new one
+ * @return byte[]
+ */
+ public byte[] getData(boolean getalive, boolean reset) {
+ if ( reset ) dataPkg = null;
+ //look in cache first
+ if ( dataPkg!=null ) {
+ if ( getalive ) {
+ //you'd be surprised, but System.currentTimeMillis
+ //shows up on the profiler
+ long alive=System.currentTimeMillis()-getServiceStartTime();
+ XByteBuffer.toBytes( (long) alive, dataPkg, TRIBES_MBR_BEGIN.length+4);
+ }
+ return dataPkg;
+ }
+
+ //package looks like
+ //start package TRIBES_MBR_BEGIN.length
+ //package length - 4 bytes
+ //alive - 8 bytes
+ //port - 4 bytes
+ //secure port - 4 bytes
+ //host length - 1 byte
+ //host - hl bytes
+ //clen - 4 bytes
+ //command - clen bytes
+ //dlen - 4 bytes
+ //domain - dlen bytes
+ //uniqueId - 16 bytes
+ //payload length - 4 bytes
+ //payload plen bytes
+ //end package TRIBES_MBR_END.length
+ byte[] addr = host;
+ long alive=System.currentTimeMillis()-getServiceStartTime();
+ byte hl = (byte)addr.length;
+ byte[] data = new byte[getDataLength()];
+
+ int bodylength = (getDataLength() - TRIBES_MBR_BEGIN.length - TRIBES_MBR_END.length - 4);
+
+ int pos = 0;
+
+ //TRIBES_MBR_BEGIN
+ System.arraycopy(TRIBES_MBR_BEGIN,0,data,pos,TRIBES_MBR_BEGIN.length);
+ pos += TRIBES_MBR_BEGIN.length;
+
+ //body length
+ XByteBuffer.toBytes(bodylength,data,pos);
+ pos += 4;
+
+ //alive data
+ XByteBuffer.toBytes((long)alive,data,pos);
+ pos += 8;
+ //port
+ XByteBuffer.toBytes(port,data,pos);
+ pos += 4;
+ //secure port
+ XByteBuffer.toBytes(securePort,data,pos);
+ pos += 4;
+ //host length
+ data[pos++] = hl;
+ //host
+ System.arraycopy(addr,0,data,pos,addr.length);
+ pos+=addr.length;
+ //clen - 4 bytes
+ XByteBuffer.toBytes(command.length,data,pos);
+ pos+=4;
+ //command - clen bytes
+ System.arraycopy(command,0,data,pos,command.length);
+ pos+=command.length;
+ //dlen - 4 bytes
+ XByteBuffer.toBytes(domain.length,data,pos);
+ pos+=4;
+ //domain - dlen bytes
+ System.arraycopy(domain,0,data,pos,domain.length);
+ pos+=domain.length;
+ //unique Id
+ System.arraycopy(uniqueId,0,data,pos,uniqueId.length);
+ pos+=uniqueId.length;
+ //payload
+ XByteBuffer.toBytes(payload.length,data,pos);
+ pos+=4;
+ System.arraycopy(payload,0,data,pos,payload.length);
+ pos+=payload.length;
+
+ //TRIBES_MBR_END
+ System.arraycopy(TRIBES_MBR_END,0,data,pos,TRIBES_MBR_END.length);
+ pos += TRIBES_MBR_END.length;
+
+ //create local data
+ dataPkg = data;
+ return data;
+ }
+ /**
+ * Deserializes a member from data sent over the wire
+ * @param data - the bytes received
+ * @return a member object.
+ */
+ public static MemberImpl getMember(byte[] data, MemberImpl member) {
+ return getMember(data,0,data.length,member);
+ }
+
+ public static MemberImpl getMember(byte[] data, int offset, int length, MemberImpl member) {
+ //package looks like
+ //start package TRIBES_MBR_BEGIN.length
+ //package length - 4 bytes
+ //alive - 8 bytes
+ //port - 4 bytes
+ //secure port - 4 bytes
+ //host length - 1 byte
+ //host - hl bytes
+ //clen - 4 bytes
+ //command - clen bytes
+ //dlen - 4 bytes
+ //domain - dlen bytes
+ //uniqueId - 16 bytes
+ //payload length - 4 bytes
+ //payload plen bytes
+ //end package TRIBES_MBR_END.length
+
+ int pos = offset;
+
+ if (XByteBuffer.firstIndexOf(data,offset,TRIBES_MBR_BEGIN)!=pos) {
+ throw new IllegalArgumentException("Invalid package, should start with:"+org.apache.catalina.tribes.util.Arrays.toString(TRIBES_MBR_BEGIN));
+ }
+
+ if ( length < (TRIBES_MBR_BEGIN.length+4) ) {
+ throw new ArrayIndexOutOfBoundsException("Member package to small to validate.");
+ }
+
+ pos += TRIBES_MBR_BEGIN.length;
+
+ int bodylength = XByteBuffer.toInt(data,pos);
+ pos += 4;
+
+ if ( length < (bodylength+4+TRIBES_MBR_BEGIN.length+TRIBES_MBR_END.length) ) {
+ throw new ArrayIndexOutOfBoundsException("Not enough bytes in member package.");
+ }
+
+ int endpos = pos+bodylength;
+ if (XByteBuffer.firstIndexOf(data,endpos,TRIBES_MBR_END)!=endpos) {
+ throw new IllegalArgumentException("Invalid package, should end with:"+org.apache.catalina.tribes.util.Arrays.toString(TRIBES_MBR_END));
+ }
+
+
+ byte[] alived = new byte[8];
+ System.arraycopy(data, pos, alived, 0, 8);
+ pos += 8;
+ byte[] portd = new byte[4];
+ System.arraycopy(data, pos, portd, 0, 4);
+ pos += 4;
+
+ byte[] sportd = new byte[4];
+ System.arraycopy(data, pos, sportd, 0, 4);
+ pos += 4;
+
+
+
+ byte hl = data[pos++];
+ byte[] addr = new byte[hl];
+ System.arraycopy(data, pos, addr, 0, hl);
+ pos += hl;
+
+ int cl = XByteBuffer.toInt(data, pos);
+ pos += 4;
+
+ byte[] command = new byte[cl];
+ System.arraycopy(data, pos, command, 0, command.length);
+ pos += command.length;
+
+ int dl = XByteBuffer.toInt(data, pos);
+ pos += 4;
+
+ byte[] domain = new byte[dl];
+ System.arraycopy(data, pos, domain, 0, domain.length);
+ pos += domain.length;
+
+ byte[] uniqueId = new byte[16];
+ System.arraycopy(data, pos, uniqueId, 0, 16);
+ pos += 16;
+
+ int pl = XByteBuffer.toInt(data, pos);
+ pos += 4;
+
+ byte[] payload = new byte[pl];
+ System.arraycopy(data, pos, payload, 0, payload.length);
+ pos += payload.length;
+
+ member.setHost(addr);
+ member.setPort(XByteBuffer.toInt(portd, 0));
+ member.setSecurePort(XByteBuffer.toInt(sportd, 0));
+ member.setMemberAliveTime(XByteBuffer.toLong(alived, 0));
+ member.setUniqueId(uniqueId);
+ member.payload = payload;
+ member.domain = domain;
+ member.command = command;
+
+ member.dataPkg = new byte[length];
+ System.arraycopy(data, offset, member.dataPkg, 0, length);
+
+ return member;
+ }
+
+ public static MemberImpl getMember(byte[] data) {
+ return getMember(data,new MemberImpl());
+ }
+
+ /**
+ * Return the name of this object
+ * @return a unique name to the cluster
+ */
+ public String getName() {
+ return "tcp://"+getHostname()+":"+getPort();
+ }
+
+ /**
+ * Return the listen port of this member
+ * @return - tcp listen port
+ */
+ public int getPort() {
+ return this.port;
+ }
+
+ /**
+ * Return the TCP listen host for this member
+ * @return IP address or host name
+ */
+ public byte[] getHost() {
+ return host;
+ }
+
+ public String getHostname() {
+ if ( this.hostname != null ) return hostname;
+ else {
+ try {
+ this.hostname = java.net.InetAddress.getByAddress(host).getHostName();
+ return this.hostname;
+ }catch ( IOException x ) {
+ throw new RuntimeException("Unable to parse hostname.",x);
+ }
+ }
+ }
+
+ /**
+ * Contains information on how long this member has been online.
+ * The result is the number of milli seconds this member has been
+ * broadcasting its membership to the cluster.
+ * @return nr of milliseconds since this member started.
+ */
+ public long getMemberAliveTime() {
+ return memberAliveTime;
+ }
+
+ public long getServiceStartTime() {
+ return serviceStartTime;
+ }
+
+ public byte[] getUniqueId() {
+ return uniqueId;
+ }
+
+ public byte[] getPayload() {
+ return payload;
+ }
+
+ public byte[] getCommand() {
+ return command;
+ }
+
+ public byte[] getDomain() {
+ return domain;
+ }
+
+ public int getSecurePort() {
+ return securePort;
+ }
+
+ public void setMemberAliveTime(long time) {
+ memberAliveTime=time;
+ }
+
+
+
+ /**
+ * String representation of this object
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer("org.apache.catalina.tribes.membership.MemberImpl[");
+ buf.append(getName()).append(",");
+ buf.append(getHostname()).append(",");
+ buf.append(port).append(", alive=");
+ buf.append(memberAliveTime).append(",");
+ buf.append("id=").append(bToS(this.uniqueId)).append(", ");
+ buf.append("payload=").append(bToS(this.payload,8)).append(", ");
+ buf.append("command=").append(bToS(this.command,8)).append(", ");
+ buf.append("domain=").append(bToS(this.domain,8)).append(", ");
+ buf.append("]");
+ return buf.toString();
+ }
+ public static String bToS(byte[] data) {
+ return bToS(data,data.length);
+ }
+ public static String bToS(byte[] data, int max) {
+ StringBuffer buf = new StringBuffer(4*16);
+ buf.append("{");
+ for (int i=0; data!=null && i<data.length; i++ ) {
+ buf.append(String.valueOf(data[i])).append(" ");
+ if ( i==max ) {
+ buf.append("...("+data.length+")");
+ break;
+ }
+ }
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ * @return The hash code
+ */
+ public int hashCode() {
+ return getHost()[0]+getHost()[1]+getHost()[2]+getHost()[3];
+ }
+
+ /**
+ * Returns true if the param o is a McastMember with the same name
+ * @param o
+ */
+ public boolean equals(Object o) {
+ if ( o instanceof MemberImpl ) {
+ return Arrays.equals(this.getHost(),((MemberImpl)o).getHost()) &&
+ this.getPort() == ((MemberImpl)o).getPort() &&
+ Arrays.equals(this.getUniqueId(),((MemberImpl)o).getUniqueId());
+ }
+ else
+ return false;
+ }
+
+ public void setHost(byte[] host) {
+ this.host = host;
+ }
+
+ public void setHostname(String host) throws IOException {
+ hostname = host;
+ this.host = java.net.InetAddress.getByName(host).getAddress();
+ }
+
+ public void setMsgCount(int msgCount) {
+ this.msgCount = msgCount;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ this.dataPkg = null;
+ }
+
+ public void setServiceStartTime(long serviceStartTime) {
+ this.serviceStartTime = serviceStartTime;
+ }
+
+ public void setUniqueId(byte[] uniqueId) {
+ this.uniqueId = uniqueId!=null?uniqueId:new byte[16];
+ getData(true,true);
+ }
+
+ public void setPayload(byte[] payload) {
+ byte[] oldpayload = this.payload;
+ this.payload = payload!=null?payload:new byte[0];
+ if ( this.getData(true,true).length > McastServiceImpl.MAX_PACKET_SIZE ) {
+ this.payload = oldpayload;
+ throw new IllegalArgumentException("Payload is to large for tribes to handle.");
+ }
+
+ }
+
+ public void setCommand(byte[] command) {
+ this.command = command!=null?command:new byte[0];
+ getData(true,true);
+ }
+
+ public void setDomain(byte[] domain) {
+ this.domain = domain!=null?domain:new byte[0];
+ getData(true,true);
+ }
+
+ public void setSecurePort(int securePort) {
+ this.securePort = securePort;
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ int length = in.readInt();
+ byte[] message = new byte[length];
+ in.read(message);
+ getMember(message,this);
+
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ byte[] data = this.getData();
+ out.writeInt(data.length);
+ out.write(data);
+ }
+
+}
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/MemberImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/MemberImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/Membership.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/Membership.java?view=diff&rev=467222&r1=467221&r2=467222
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/Membership.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/Membership.java Mon Oct 23 20:17:11 2006
@@ -1,325 +1,325 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.catalina.tribes.membership;
-
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.catalina.tribes.Member;
-import java.util.Comparator;
-
-/**
- * A <b>membership</b> implementation using simple multicast.
- * This is the representation of a multicast membership.
- * This class is responsible for maintaining a list of active cluster nodes in the cluster.
- * If a node fails to send out a heartbeat, the node will be dismissed.
- *
- * @author Filip Hanik
- * @author Peter Rossbach
- * @version $Revision: 356540 $, $Date: 2005-12-13 10:53:40 -0600 (Tue, 13 Dec 2005) $
- */
-public class Membership
-{
- protected static final MemberImpl[] EMPTY_MEMBERS = new MemberImpl[0];
-
- /**
- * The name of this membership, has to be the same as the name for the local
- * member
- */
- protected MemberImpl local;
-
- /**
- * A map of all the members in the cluster.
- */
- protected HashMap map = new HashMap();
-
- /**
- * A list of all the members in the cluster.
- */
- protected MemberImpl[] members = EMPTY_MEMBERS;
-
- /**
- * sort members by alive time
- */
- protected Comparator memberComparator = new MemberComparator();
-
- public Object clone() {
- synchronized (members) {
- Membership clone = new Membership(local, memberComparator);
- clone.map = (HashMap) map.clone();
- clone.members = new MemberImpl[members.length];
- System.arraycopy(members,0,clone.members,0,members.length);
- return clone;
- }
- }
-
- /**
- * Constructs a new membership
- * @param name - has to be the name of the local member. Used to filter the local member from the cluster membership
- */
- public Membership(MemberImpl local, boolean includeLocal) {
- this.local = local;
- if ( includeLocal ) addMember(local);
- }
-
- public Membership(MemberImpl local) {
- this(local,false);
- }
-
- public Membership(MemberImpl local, Comparator comp) {
- this(local,comp,false);
- }
-
- public Membership(MemberImpl local, Comparator comp, boolean includeLocal) {
- this(local,includeLocal);
- this.memberComparator = comp;
- }
- /**
- * Reset the membership and start over fresh.
- * Ie, delete all the members and wait for them to ping again and join this membership
- */
- public synchronized void reset() {
- map.clear();
- members = EMPTY_MEMBERS ;
- }
-
- /**
- * Notify the membership that this member has announced itself.
- *
- * @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 or updated.
- */
- public synchronized boolean memberAlive(MemberImpl member) {
- boolean result = false;
- //ignore ourselves
- if ( member.equals(local) ) return result;
-
- //return true if the membership has changed
- MbrEntry entry = (MbrEntry)map.get(member);
- if ( entry == null ) {
- entry = addMember(member);
- result = true;
- } else {
- //update the member alive time
- MemberImpl updateMember = entry.getMember() ;
- if(updateMember.getMemberAliveTime() != member.getMemberAliveTime()) {
- //update fields that can change
- updateMember.setMemberAliveTime(member.getMemberAliveTime());
- updateMember.setPayload(member.getPayload());
- updateMember.setCommand(member.getCommand());
- 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
- */
- public synchronized MbrEntry addMember(MemberImpl member) {
- synchronized (members) {
- MbrEntry entry = new MbrEntry(member);
- if (!map.containsKey(member) ) {
- map.put(member, entry);
- MemberImpl results[] = new MemberImpl[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);
- }
- return entry;
- }
- }
-
- /**
- * Remove a member from this component.
- *
- * @param member The member to remove
- */
- public void removeMember(MemberImpl member) {
- map.remove(member);
- synchronized (members) {
- int n = -1;
- for (int i = 0; i < members.length; i++) {
- if (members[i] == member || members[i].equals(member)) {
- n = i;
- break;
- }
- }
- if (n < 0) return;
- MemberImpl results[] = new MemberImpl[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()
- * @param maxtime - the max time a member can remain unannounced before it is considered dead.
- * @return the list of expired members
- */
- public synchronized MemberImpl[] expire(long 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());
- }
- }
-
- if(list != null) {
- MemberImpl[] result = new MemberImpl[list.size()];
- list.toArray(result);
- for( int j=0; j<result.length; j++) {
- removeMember(result[j]);
- }
- return result;
- } else {
- return EMPTY_MEMBERS ;
- }
- }
-
- /**
- * Returning that service has members or not
- */
- public boolean hasMembers() {
- return members.length > 0 ;
- }
-
-
- public MemberImpl getMember(Member mbr) {
- if(hasMembers()) {
- MemberImpl result = null;
- for ( int i=0; i<this.members.length && result==null; i++ ) {
- if ( members[i].equals(mbr) ) result = members[i];
- }//for
- return result;
- } else {
- return null;
- }
- }
-
- public boolean contains(Member mbr) {
- return getMember(mbr)!=null;
- }
-
- /**
- * Returning a list of all the members in the membership
- * We not need a copy: add and remove generate new arrays.
- */
- public MemberImpl[] getMembers() {
- 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()];
- java.util.Iterator i = map.entrySet().iterator();
- int pos = 0;
- while ( i.hasNext() )
- 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((MemberImpl) o1, (MemberImpl) o2);
- } catch (ClassCastException x) {
- return 0;
- }
- }
-
- public int compare(MemberImpl m1, MemberImpl 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
- */
- protected static class MbrEntry
- {
-
- protected MemberImpl mbr;
- protected long lastHeardFrom;
-
- public MbrEntry(MemberImpl mbr) {
- this.mbr = mbr;
- }
-
- /**
- * Indicate that this member has been accessed.
- */
- public void accessed(){
- lastHeardFrom = System.currentTimeMillis();
- }
-
- /**
- * Return the actual Member object
- */
- public MemberImpl getMember() {
- return mbr;
- }
-
- /**
- * Check if this dude has expired
- * @param maxtime The time threshold
- */
- public boolean hasExpired(long maxtime) {
- long delta = System.currentTimeMillis() - lastHeardFrom;
- return delta > maxtime;
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.tribes.membership;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.catalina.tribes.Member;
+import java.util.Comparator;
+
+/**
+ * A <b>membership</b> implementation using simple multicast.
+ * This is the representation of a multicast membership.
+ * This class is responsible for maintaining a list of active cluster nodes in the cluster.
+ * 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 Membership
+{
+ protected static final MemberImpl[] EMPTY_MEMBERS = new MemberImpl[0];
+
+ /**
+ * The name of this membership, has to be the same as the name for the local
+ * member
+ */
+ protected MemberImpl local;
+
+ /**
+ * A map of all the members in the cluster.
+ */
+ protected HashMap map = new HashMap();
+
+ /**
+ * A list of all the members in the cluster.
+ */
+ protected MemberImpl[] members = EMPTY_MEMBERS;
+
+ /**
+ * sort members by alive time
+ */
+ protected Comparator memberComparator = new MemberComparator();
+
+ public Object clone() {
+ synchronized (members) {
+ Membership clone = new Membership(local, memberComparator);
+ clone.map = (HashMap) map.clone();
+ clone.members = new MemberImpl[members.length];
+ System.arraycopy(members,0,clone.members,0,members.length);
+ return clone;
+ }
+ }
+
+ /**
+ * Constructs a new membership
+ * @param name - has to be the name of the local member. Used to filter the local member from the cluster membership
+ */
+ public Membership(MemberImpl local, boolean includeLocal) {
+ this.local = local;
+ if ( includeLocal ) addMember(local);
+ }
+
+ public Membership(MemberImpl local) {
+ this(local,false);
+ }
+
+ public Membership(MemberImpl local, Comparator comp) {
+ this(local,comp,false);
+ }
+
+ public Membership(MemberImpl local, Comparator comp, boolean includeLocal) {
+ this(local,includeLocal);
+ this.memberComparator = comp;
+ }
+ /**
+ * Reset the membership and start over fresh.
+ * Ie, delete all the members and wait for them to ping again and join this membership
+ */
+ public synchronized void reset() {
+ map.clear();
+ members = EMPTY_MEMBERS ;
+ }
+
+ /**
+ * Notify the membership that this member has announced itself.
+ *
+ * @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 or updated.
+ */
+ public synchronized boolean memberAlive(MemberImpl member) {
+ boolean result = false;
+ //ignore ourselves
+ if ( member.equals(local) ) return result;
+
+ //return true if the membership has changed
+ MbrEntry entry = (MbrEntry)map.get(member);
+ if ( entry == null ) {
+ entry = addMember(member);
+ result = true;
+ } else {
+ //update the member alive time
+ MemberImpl updateMember = entry.getMember() ;
+ if(updateMember.getMemberAliveTime() != member.getMemberAliveTime()) {
+ //update fields that can change
+ updateMember.setMemberAliveTime(member.getMemberAliveTime());
+ updateMember.setPayload(member.getPayload());
+ updateMember.setCommand(member.getCommand());
+ 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
+ */
+ public synchronized MbrEntry addMember(MemberImpl member) {
+ synchronized (members) {
+ MbrEntry entry = new MbrEntry(member);
+ if (!map.containsKey(member) ) {
+ map.put(member, entry);
+ MemberImpl results[] = new MemberImpl[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);
+ }
+ return entry;
+ }
+ }
+
+ /**
+ * Remove a member from this component.
+ *
+ * @param member The member to remove
+ */
+ public void removeMember(MemberImpl member) {
+ map.remove(member);
+ synchronized (members) {
+ int n = -1;
+ for (int i = 0; i < members.length; i++) {
+ if (members[i] == member || members[i].equals(member)) {
+ n = i;
+ break;
+ }
+ }
+ if (n < 0) return;
+ MemberImpl results[] = new MemberImpl[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()
+ * @param maxtime - the max time a member can remain unannounced before it is considered dead.
+ * @return the list of expired members
+ */
+ public synchronized MemberImpl[] expire(long 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());
+ }
+ }
+
+ if(list != null) {
+ MemberImpl[] result = new MemberImpl[list.size()];
+ list.toArray(result);
+ for( int j=0; j<result.length; j++) {
+ removeMember(result[j]);
+ }
+ return result;
+ } else {
+ return EMPTY_MEMBERS ;
+ }
+ }
+
+ /**
+ * Returning that service has members or not
+ */
+ public boolean hasMembers() {
+ return members.length > 0 ;
+ }
+
+
+ public MemberImpl getMember(Member mbr) {
+ if(hasMembers()) {
+ MemberImpl result = null;
+ for ( int i=0; i<this.members.length && result==null; i++ ) {
+ if ( members[i].equals(mbr) ) result = members[i];
+ }//for
+ return result;
+ } else {
+ return null;
+ }
+ }
+
+ public boolean contains(Member mbr) {
+ return getMember(mbr)!=null;
+ }
+
+ /**
+ * Returning a list of all the members in the membership
+ * We not need a copy: add and remove generate new arrays.
+ */
+ public MemberImpl[] getMembers() {
+ 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()];
+ java.util.Iterator i = map.entrySet().iterator();
+ int pos = 0;
+ while ( i.hasNext() )
+ 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((MemberImpl) o1, (MemberImpl) o2);
+ } catch (ClassCastException x) {
+ return 0;
+ }
+ }
+
+ public int compare(MemberImpl m1, MemberImpl 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
+ */
+ protected static class MbrEntry
+ {
+
+ protected MemberImpl mbr;
+ protected long lastHeardFrom;
+
+ public MbrEntry(MemberImpl mbr) {
+ this.mbr = mbr;
+ }
+
+ /**
+ * Indicate that this member has been accessed.
+ */
+ public void accessed(){
+ lastHeardFrom = System.currentTimeMillis();
+ }
+
+ /**
+ * Return the actual Member object
+ */
+ public MemberImpl getMember() {
+ return mbr;
+ }
+
+ /**
+ * Check if this dude has expired
+ * @param maxtime The time threshold
+ */
+ public boolean hasExpired(long maxtime) {
+ long delta = System.currentTimeMillis() - lastHeardFrom;
+ return delta > maxtime;
+ }
+ }
+}
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/Membership.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/Membership.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/StaticMember.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/StaticMember.java?view=diff&rev=467222&r1=467221&r2=467222
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/StaticMember.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/StaticMember.java Mon Oct 23 20:17:11 2006
@@ -1,80 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.catalina.tribes.membership;
-
-import java.io.IOException;
-import org.apache.catalina.tribes.util.UUIDGenerator;
-import org.apache.catalina.tribes.util.Arrays;
-
-/**
- * <p>Title: </p>
- *
- * <p>Description: </p>
- *
- * <p>Copyright: Copyright (c) 2006</p>
- *
- * <p>Company: </p>
- *
- * @author not attributable
- * @version 1.0
- */
-public class StaticMember extends MemberImpl {
- public StaticMember() {
- super();
- }
-
- public StaticMember(String host, int port, long aliveTime) throws IOException {
- super(host, port, aliveTime);
- }
-
- public StaticMember(String host, int port, long aliveTime, byte[] payload) throws IOException {
- super(host, port, aliveTime, payload);
- }
-
- /**
- * @param host String, either in byte array string format, like {214,116,1,3}
- * or as a regular hostname, 127.0.0.1 or tomcat01.mydomain.com
- */
- public void setHost(String host) {
- if ( host == null ) return;
- if ( host.startsWith("{") ) setHost(Arrays.fromString(host));
- else try { setHostname(host); }catch (IOException x) { throw new RuntimeException(x);}
-
- }
-
- /**
- * @param domain String, either in byte array string format, like {214,116,1,3}
- * or as a regular string value like 'mydomain'. The latter will be converted using ISO-8859-1 encoding
- */
- public void setDomain(String domain) {
- if ( domain == null ) return;
- if ( domain.startsWith("{") ) setDomain(Arrays.fromString(domain));
- else setDomain(Arrays.convert(domain));
- }
-
- /**
- * @param id String, must be in byte array string format, like {214,116,1,3} and exactly 16 bytes long
- */
- public void setUniqueId(String id) {
- byte[] uuid = Arrays.fromString(id);
- if ( uuid==null || uuid.length != 16 ) throw new RuntimeException("UUID must be exactly 16 bytes, not:"+id);
- setUniqueId(uuid);
- }
-
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.tribes.membership;
+
+import java.io.IOException;
+import org.apache.catalina.tribes.util.UUIDGenerator;
+import org.apache.catalina.tribes.util.Arrays;
+
+/**
+ * <p>Title: </p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2006</p>
+ *
+ * <p>Company: </p>
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class StaticMember extends MemberImpl {
+ public StaticMember() {
+ super();
+ }
+
+ public StaticMember(String host, int port, long aliveTime) throws IOException {
+ super(host, port, aliveTime);
+ }
+
+ public StaticMember(String host, int port, long aliveTime, byte[] payload) throws IOException {
+ super(host, port, aliveTime, payload);
+ }
+
+ /**
+ * @param host String, either in byte array string format, like {214,116,1,3}
+ * or as a regular hostname, 127.0.0.1 or tomcat01.mydomain.com
+ */
+ public void setHost(String host) {
+ if ( host == null ) return;
+ if ( host.startsWith("{") ) setHost(Arrays.fromString(host));
+ else try { setHostname(host); }catch (IOException x) { throw new RuntimeException(x);}
+
+ }
+
+ /**
+ * @param domain String, either in byte array string format, like {214,116,1,3}
+ * or as a regular string value like 'mydomain'. The latter will be converted using ISO-8859-1 encoding
+ */
+ public void setDomain(String domain) {
+ if ( domain == null ) return;
+ if ( domain.startsWith("{") ) setDomain(Arrays.fromString(domain));
+ else setDomain(Arrays.convert(domain));
+ }
+
+ /**
+ * @param id String, must be in byte array string format, like {214,116,1,3} and exactly 16 bytes long
+ */
+ public void setUniqueId(String id) {
+ byte[] uuid = Arrays.fromString(id);
+ if ( uuid==null || uuid.length != 16 ) throw new RuntimeException("UUID must be exactly 16 bytes, not:"+id);
+ setUniqueId(uuid);
+ }
+
+
}
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/StaticMember.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/StaticMember.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/mbeans-descriptors.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/membership/mbeans-descriptors.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/tribes/package.html
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org