Project: Tomcat
Bug 47234 serviceStartTime is different in MemberImpl from McastServiceImpl
Reported: 2009-05-21 07:32:52 | Status: resolved fixed

Hi, I'm using the tribes cluster module in my own application (which has nothing to do with tomcat) and I'm using the member alive time value to sort all the cluster members. This bug produces the following: I have 2 nodes that were started almost at the same time and both nodes claim that the other node was started before them NODE1: Remote members: (-52.63.57.110:4001 ready=true suspect=false failing=false aliveTime=1526) Local member: (-52.63.57.109:4000 ready=true suspect=false failing=false aliveTime=1236) NODE2: Remote members: (-52.63.57.109:4000 ready=true suspect=false failing=false aliveTime=2021) Local member: (-52.63.57.110:4001 ready=true suspect=false failing=false aliveTime=1069) My code do the following: Member[] members = groupChannel.getMembers(); printRemote(members); Member localMember = groupChannel.getLocalMember(true); printLocal(localMember); In that code (due to timing issues) it should possible the other way around (that every node claim to be started before the other) but not that case. The issue occurs because when the McastService is started, it assigns a start time to the local member. public class McastService .... { public void start(int level) { .... localMember.setServiceStartTime(System.currentTimeMillis()); .... impl = new McastServiceImpl(localMember, ....); impl.start(level); } } But, then it creates and starts a McastServiceImpl which also stores a new serviceStartTime :-( public class McastServiceImpl { protected long serviceStartTime; public void start(int level) { .... serviceStartTime = System.currentTimeMillis(); .... } } So, we have 2 different start times. Unfortunately both times are used: To get the local member, the impl.getServiceStartTime() is used: public class McastService .... { public Member getLocalMember(boolean alive) { if ( alive && localMember != null && impl != null) localMember.setMemberAliveTime(System.currentTimeMillis()-impl.getServiceStartTime()); return localMember; } } But, when the member is transmited throw the network, the MemberImpl.getServiceStartTime() is used. public class MemberImpl .... { 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; } ...... } That produces that weird behaviour. IMHO, the fix should be setting the same "serviceStartTime" to both components. This issue is affecting seriously my code. I would appreciate if you could fix it asap. I've verified that the same code is present in trunk repository. Regards, Ariel

Files changed in fix:
java/org/apache/catalina/tribes/membership/McastServiceImpl.java