Author: fhanik
Date: Fri May 26 19:32:21 2006
New Revision: 409799

URL: http://svn.apache.org/viewvc?rev=409799&view=rev
Log:
Absence reply should be sent if the message was not by an RPC channel

Modified:
    tomcat/container/tc5.5.x/modules/groupcom/doc/introduction.xml
    
tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/group/GroupChannel.java
    tomcat/container/tc5.5.x/modules/groupcom/to-do.txt

Modified: tomcat/container/tc5.5.x/modules/groupcom/doc/introduction.xml
URL: 
http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/groupcom/doc/introduction.xml?rev=409799&r1=409798&r2=409799&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/modules/groupcom/doc/introduction.xml (original)
+++ tomcat/container/tc5.5.x/modules/groupcom/doc/introduction.xml Fri May 26 
19:32:21 2006
@@ -31,33 +31,33 @@
       <source>
         //create a channel
         Channel myChannel = new GroupChannel();
-        
+
         //create my listeners
-        MyMessageListener msgListener = new MyMessageListener();
-        MyMemberListener mbrListener = new MyMemberListener();
-        
+        ChannelListener msgListener = new MyMessageListener();
+        MembershipListener mbrListener = new MyMemberListener();
+
         //attach the listeners to the channel
         myChannel.addMembershipListener(mbrListener);
         myChannel.addChannelListener(msgListener);
-        
+
         //start the channel
         myChannel.start(Channel.DEFAULT);
-        
+
         //create a message to be sent, message must implement 
java.io.Serializable
         //for performance reasons you probably want them to implement 
java.io.Externalizable
         Serializable myMsg = new MyMessage();
 
         //retrieve my current members
         Member[] group = myChannel.getMembers();
-        
+
         //send the message
         channel.send(group,myMsg,Channel.SEND_OPTIONS_DEFAULT);
       </source>
     </li>
   </ul>
   <p>
-      Simple yeah? There is a lot more to Tribes than we have shown, hopefully 
the docs will be able 
-      to explain more to you. Remember, that we are always interested in 
suggestions, improvements, bug fixes 
+      Simple yeah? There is a lot more to Tribes than we have shown, hopefully 
the docs will be able
+      to explain more to you. Remember, that we are always interested in 
suggestions, improvements, bug fixes
       and anything that you think would help this project.
   </p>
   <p>
@@ -70,20 +70,20 @@
   <p>
     Tribes is a messaging framework with group communication abilities. Tribes 
allows you to send and receive
     messages over a network, it also allows for dynamic discovery of other 
nodes in the network.<br/>
-    And that is the short story, it really is as simple as that. What makes 
Tribes useful and unique will be 
+    And that is the short story, it really is as simple as that. What makes 
Tribes useful and unique will be
     described in the section below.<br/>
   </p>
   <p>
-    The Tribes module was started early 2006 and a small part of the code base 
comes from the clustering module 
-    that has been existing since 2003 or 2004. 
-    The current cluster implementation has several short comings and many work 
arounds were created due 
+    The Tribes module was started early 2006 and a small part of the code base 
comes from the clustering module
+    that has been existing since 2003 or 2004.
+    The current cluster implementation has several short comings and many work 
arounds were created due
     to the complexity in group communication. Long story short, what should 
have been two modules a long time
-    ago, will be now. Tribes takes out the complexity of messaging from the 
replication module and becomes 
+    ago, will be now. Tribes takes out the complexity of messaging from the 
replication module and becomes
     a fully independent and highly flexible group communication module.<br/>
   </p>
   <p>
     In Tomcat the old <code>modules/cluster</code> has now become 
<code>modules/groupcom</code>(Tribes) and
-    <code>modules/ha</code> (replication). This will allow development to 
proceed and let the developers 
+    <code>modules/ha</code> (replication). This will allow development to 
proceed and let the developers
     focus on the issues they are actually working on rather than getting 
boggled down in details of a module
     they are not interested in. The understanding is that both communication 
and replication are complex enough,
     and when trying to develop them in the same module, well you know, it 
becomes a cluster :)<br/>
@@ -92,14 +92,14 @@
     Tribes allows for guaranteed messaging, and can be customized in many 
ways. Why is this important?<br/>
     Well, you as a developer want to know that the messages you are sending 
are reaching their destination.
     More than that, if a message doesn't reach its destination, the 
application on top of Tribes will be notified
-    that the message was never sent, and what node it failed. 
+    that the message was never sent, and what node it failed.
   </p>
-  
+
 </section>
 
 <section name="Why another messaging framework">
   <p>
-    I am a big fan of reusing code and would never dream of developing 
something if someone else has already 
+    I am a big fan of reusing code and would never dream of developing 
something if someone else has already
     done it and it was available to me and the community I try to serve.<br/>
     When I did my research to improve the clustering module I was constantly 
faced with a few obstacles:<br/>
     1. The framework wasn't flexible enough<br/>
@@ -110,8 +110,8 @@
     And the list continues...
   </p>
   <p>
-    So I came up with Tribes, to address these issues and other issues that 
came along. 
-    When designing Tribes I wanted to make sure I didn't lose any of the 
flexibility and 
+    So I came up with Tribes, to address these issues and other issues that 
came along.
+    When designing Tribes I wanted to make sure I didn't lose any of the 
flexibility and
     delivery semantics that the existing frameworks already delivered. The 
goal was to create a framework
     that could do everything that the others already did, but to provide more 
flexibility for the application
     developer. In the next section will give you the high level overview of 
what features tribes offers or will offer.
@@ -142,7 +142,7 @@
     There are three different levels of delivery guarantee when a message is 
sent.<br/>
     <ol>
       <li>IO Based send guarantee. - fastest, least reliable<br/>
-          This means that Tribes considers the message transfer to be 
successful 
+          This means that Tribes considers the message transfer to be 
successful
           if the message was sent to the socket send buffer and accepted.<br/>
           On blocking IO, this would be 
<code>socket.getOutputStream().write(msg)</code><br/>
           On non blocking IO, this would be 
<code>socketChannel.write()</code>, and the buffer byte buffer gets emptied
@@ -166,8 +166,8 @@
           and associate that exception with the member that didn't process the 
message.
       </li>
     </ol>
-    You can of course write even more sophisticated guarantee levels, and some 
of them will be mentioned later on 
-    in the documentation. One mentionable level would be a 2-Phase-Commit, 
where the remote applications don't receive 
+    You can of course write even more sophisticated guarantee levels, and some 
of them will be mentioned later on
+    in the documentation. One mentionable level would be a 2-Phase-Commit, 
where the remote applications don't receive
     the message until all nodes have received the message. Sort of like a 
all-or-nothing protocol.
   </p>
   <p>
@@ -191,14 +191,14 @@
       Message_9 - RPC message, asynchronous, don't wait for a reply, collect 
them via a callback
       Message_10- sent to a member that is not part of this group
     </source>
-    As you can imagine by now, these are just examples. The number of 
different semantics you can apply on a 
+    As you can imagine by now, these are just examples. The number of 
different semantics you can apply on a
     per-message-basis is almost limitless. Tribes allows you to set up to 28 
different on a message
     and then configure Tribes to what flag results in what action on the 
message.<br/>
     Imagine a shared transactional cache, probably &gt;90% are reads, and the 
dirty reads should be completely
-    unordered and delivered as fast as possible. But transactional writes on 
the other hand, have to 
+    unordered and delivered as fast as possible. But transactional writes on 
the other hand, have to
     be ordered so that no cache gets corrupted. With tribes you would send the 
write messages totally ordered,
     while the read messages you simple fire to achieve highest throughput.<br/>
-    There are probably better examples on how this powerful feature can be 
used, so use your imagination and 
+    There are probably better examples on how this powerful feature can be 
used, so use your imagination and
     your experience to think of how this could benefit you in your application.
   </p>
   <p>
@@ -211,7 +211,7 @@
     by the applications running on top of Tribes.<br/>
     This is how Tribes is able to send some messages totally ordered and 
others fire and forget style
     like the example above.<br/>
-    The number of interceptors that are available will keep growing, and we 
would appreciate any contributions 
+    The number of interceptors that are available will keep growing, and we 
would appreciate any contributions
     that you might have.
   </p>
   <p>
@@ -221,20 +221,20 @@
     The exception is the <code>MessageDispatchInterceptor</code> that will 
queue up the message
     and send it on a separate thread for asynchronous message delivery.
     Messages received are controlled by a thread pool in the 
<code>receiver</code> component.<br/>
-    The channel object can send a <code>heartbeat()</code> through the 
interceptor stack to allow 
+    The channel object can send a <code>heartbeat()</code> through the 
interceptor stack to allow
     for timeouts, cleanup and other events.<br/>
     The <code>MessageDispatchInterceptor</code> is the only interceptor that 
is configured by default.
   </p>
   <p>
     <b>Parallel Delivery</b><br/>
-    Tribes support parallel delivery of messages. Meaning that node_A could 
send three messages to node_B in 
+    Tribes support parallel delivery of messages. Meaning that node_A could 
send three messages to node_B in
     parallel. This feature becomes useful when sending messages with different 
delivery semantics.
     Otherwise if Message_1 was sent totally ordered, Message_2 would have to 
wait for that message to complete.<br/>
     Through NIO, Tribes is also able to send a message to several receivers at 
the same time on the same thread.
   </p>
   <p>
     <b>Silent Member Messaging</b><br/>
-    With Tribes you are able to send messages to members that are not in your 
group. 
+    With Tribes you are able to send messages to members that are not in your 
group.
     So by default, you can already send messages over a wide area network, 
even though the dynamic discover
     module today is limited to local area networks by using multicast for 
dynamic node discovery.
     Of course, the membership component will be expanded to support WAN 
memberships in the future.
@@ -247,8 +247,8 @@
     I hope you have enjoyed this short introduction to Tribes. You can 
download <a href="../apache-tribes.jar">Tribes here</a>
     or you can download Tribes <a href="../tribes-all.zip">including javadoc 
and this doc</a>
   </p>
-      
-    
+
+
 </section>
 
 <!--
@@ -289,7 +289,7 @@
     <td>acknowledge timeout and only usefull it waitForAck is true</td>
     <td><code>15000</code></td>
   </tr>
-  
+
   <tr>
     <td>waitForAck</td>
     <td>Wait for ack after data send</td>
@@ -321,9 +321,9 @@
       waitForAck="true"
       autoConnect="false"/&gt;
 </source>
-</p>  
+</p>
 </section>
-     
+
 -->
 </body>
 

Modified: 
tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/group/GroupChannel.java
URL: 
http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/group/GroupChannel.java?rev=409799&r1=409798&r2=409799&view=diff
==============================================================================
--- 
tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/group/GroupChannel.java
 (original)
+++ 
tomcat/container/tc5.5.x/modules/groupcom/src/share/org/apache/catalina/tribes/group/GroupChannel.java
 Fri May 26 19:32:21 2006
@@ -1,12 +1,12 @@
 /*
  * Copyright 1999,2004-2006 The Apache Software Foundation.
- * 
+ *
  * Licensed 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.
@@ -56,16 +56,16 @@
      */
     protected boolean heartbeat = true;
     /**
-     * If <code>heartbeat == true</code> then how often do we want this 
+     * If <code>heartbeat == true</code> then how often do we want this
      * heartbeat to run. default is one minute
      */
     protected long heartbeatSleeptime = 60*1000;//only run once a minute
-    
+
     /**
      * Internal heartbeat thread
      */
     protected HeartbeatThread hbthread = null;
-    
+
     /**
      * The  <code>ChannelCoordinator</code> coordinates the bottom layer 
components:<br>
      * - MembershipService<br>
@@ -73,39 +73,39 @@
      * - ChannelReceiver<br>
      */
     protected ChannelCoordinator coordinator = new ChannelCoordinator();
-    
+
     /**
      * The first interceptor in the inteceptor stack.
-     * The interceptors are chained in a linked list, so we only need a 
reference to the 
+     * The interceptors are chained in a linked list, so we only need a 
reference to the
      * first one
      */
     protected ChannelInterceptor interceptors = null;
-    
+
     /**
      * A list of membership listeners that subscribe to membership 
announcements
      */
     protected ArrayList membershipListeners = new ArrayList();
-    
+
     /**
      * A list of channel listeners that subscribe to incoming messages
      */
     protected ArrayList channelListeners = new ArrayList();
-    
+
     /**
-     * If set to true, the GroupChannel will check to make sure that 
+     * If set to true, the GroupChannel will check to make sure that
      */
     protected boolean optionCheck = false;
 
     /**
-     * Creates a GroupChannel. This constructor will also 
+     * Creates a GroupChannel. This constructor will also
      * add the first interceptor in the GroupChannel.<br>
      * The first interceptor is always the channel itself.
      */
     public GroupChannel() {
         addInterceptor(this);
     }
-    
-    
+
+
     /**
      * Adds an interceptor to the stack for message processing<br>
      * Interceptors are ordered in the way they are added.<br>
@@ -118,7 +118,7 @@
      * <code>Channel -> A -> C -> B -> ChannelCoordinator</code><br>
      * @param interceptor ChannelInterceptorBase
      */
-    public void addInterceptor(ChannelInterceptor interceptor) { 
+    public void addInterceptor(ChannelInterceptor interceptor) {
         if ( interceptors == null ) {
             interceptors = interceptor;
             interceptors.setNext(coordinator);
@@ -135,7 +135,7 @@
             coordinator.setPrevious(interceptor);
         }
     }
-    
+
     /**
      * Sends a heartbeat through the interceptor stack.<br>
      * Invoke this method from the application on a periodic basis if
@@ -155,8 +155,8 @@
         }
 
     }
-    
-    
+
+
     /**
      * Send a message to the destinations specified
      * @param destination Member[] - destination.length > 1
@@ -170,14 +170,14 @@
     public UniqueId send(Member[] destination, Serializable msg, int options) 
throws ChannelException {
         return send(destination,msg,options,null);
     }
-    
+
     /**
-     * 
+     *
      * @param destination Member[] - destination.length > 1
      * @param msg Serializable - the message to send
      * @param options int - sender options, options can trigger guarantee 
levels and different interceptors to
      * react to the message see class documentation for the 
<code>Channel</code> object.<br>
-     * @param handler - callback object for error handling and completion 
notification, used when a message is 
+     * @param handler - callback object for error handling and completion 
notification, used when a message is
      * sent asynchronously using the 
<code>Channel.SEND_OPTIONS_ASYNCHRONOUS</code> flag enabled.
      * @return UniqueId - the unique Id that was assigned to this message
      * @throws ChannelException - if an error occurs processing the message
@@ -218,7 +218,7 @@
             if ( buffer != null ) 
BufferPool.getBufferPool().returnBuffer(buffer);
         }
     }
-    
+
 
     /**
      * Callback from the interceptor stack. <br>
@@ -231,7 +231,7 @@
     public void messageReceived(ChannelMessage msg) {
         if ( msg == null ) return;
         try {
-            
+
             Serializable fwd = null;
             if ( (msg.getOptions() & SEND_OPTIONS_BYTE_MESSAGE) == 
SEND_OPTIONS_BYTE_MESSAGE ) {
                 fwd = new ByteMessage(msg.getMessage().getBytes());
@@ -245,7 +245,9 @@
                 ChannelListener channelListener = 
(ChannelListener)channelListeners.get(i);
                 if (channelListener != null && channelListener.accept(fwd, 
source)) {
                     channelListener.messageReceived(fwd, source);
-                    rx = true;
+                    //if the message was accepted by an RPC channel, that 
channel
+                    //is responsible for returning the reply, otherwise we 
send an absence reply
+                    if ( channelListener instanceof RpcChannel ) rx = true;
                 }
             }//for
             if ((!rx) && (fwd instanceof RpcMessage)) {
@@ -257,7 +259,7 @@
             log.error("Unable to deserialize channel message.",x);
         }
     }
-    
+
     /**
      * Sends a <code>NoRpcChannelReply</code> message to a member<br>
      * This method gets invoked by the channel if a RPC message comes in
@@ -275,7 +277,7 @@
             log.error("Unable to find rpc channel, failed to send 
NoRpcChannelReply.",x);
         }
     }
-    
+
     /**
      * memberAdded gets invoked by the interceptor below the channel
      * and the channel will broadcast it to the membership listeners
@@ -288,7 +290,7 @@
             if (membershipListener != null) 
membershipListener.memberAdded(member);
         }
     }
-    
+
     /**
      * memberDisappeared gets invoked by the interceptor below the channel
      * and the channel will broadcast it to the membership listeners
@@ -301,15 +303,15 @@
             if (membershipListener != null) 
membershipListener.memberDisappeared(member);
         }
     }
-    
+
     /**
      * Sets up the default implementation interceptor stack
      * if no interceptors have been added
      * @throws ChannelException
      */
     protected synchronized void setupDefaultStack() throws ChannelException {
-        
-        if ( getFirstInterceptor() != null && 
+
+        if ( getFirstInterceptor() != null &&
              ((getFirstInterceptor().getNext() instanceof 
ChannelCoordinator))) {
             ChannelInterceptor interceptor = null;
             Class clazz = null;
@@ -327,7 +329,7 @@
             this.addInterceptor(interceptor);
         }
     }
-    
+
     /**
      * Validates the option flags that each interceptor is using and reports
      * an error if two interceptor share the same flag.
@@ -359,9 +361,9 @@
             first = first.getNext();
         }//while
         if ( conflicts.length() > 0 ) throw new ChannelException("Interceptor 
option flag conflict: "+conflicts.toString());
-    
+
     }
-    
+
     /**
      * Starts the channel
      * @param svc int - what service to start
@@ -377,7 +379,7 @@
             hbthread.start();
         }
     }
-    
+
     /**
      * Stops the channel
      * @param svc int
@@ -391,7 +393,7 @@
         }
         super.stop(svc);
     }
-    
+
     /**
      * Returns the first interceptor of the stack. Useful for traversal.
      * @return ChannelInterceptor
@@ -400,7 +402,7 @@
         if (interceptors != null) return interceptors;
         else return coordinator;
     }
-    
+
     /**
      * Returns the channel receiver component
      * @return ChannelReceiver
@@ -408,7 +410,7 @@
     public ChannelReceiver getChannelReceiver() {
         return coordinator.getClusterReceiver();
     }
-    
+
     /**
      * Returns the channel sender component
      * @return ChannelSender
@@ -424,7 +426,7 @@
     public MembershipService getMembershipService() {
         return coordinator.getMembershipService();
     }
-    
+
     /**
      * Sets the channel receiver component
      * @param clusterReceiver ChannelReceiver
@@ -440,7 +442,7 @@
     public void setChannelSender(ChannelSender clusterSender) {
         coordinator.setClusterSender(clusterSender);
     }
-    
+
     /**
      * Sets the membership component
      * @param membershipService MembershipService
@@ -448,7 +450,7 @@
     public void setMembershipService(MembershipService membershipService) {
         coordinator.setMembershipService(membershipService);
     }
-    
+
     /**
      * Adds a membership listener to the channel.<br>
      * Membership listeners are uniquely identified using the equals(Object) 
method
@@ -464,7 +466,7 @@
      * Membership listeners are uniquely identified using the equals(Object) 
method
      * @param membershipListener MembershipListener
      */
-    
+
     public void removeMembershipListener(MembershipListener 
membershipListener) {
         membershipListeners.remove(membershipListener);
     }
@@ -478,9 +480,9 @@
         if (!this.channelListeners.contains(channelListener) )
             this.channelListeners.add(channelListener);
     }
-    
+
     /**
-     * 
+     *
      * Removes a channel listener from the channel.<br>
      * Channel listeners are uniquely identified using the equals(Object) 
method
      * @param channelListener ChannelListener
@@ -488,12 +490,12 @@
     public void removeChannelListener(ChannelListener channelListener) {
         channelListeners.remove(channelListener);
     }
-    
+
     /**
      * Returns an iterator of all the interceptors in this stack
      * @return Iterator
      */
-    public Iterator getInterceptors() { 
+    public Iterator getInterceptors() {
         return new InterceptorIterator(this.getNext(),this.coordinator);
     }
 
@@ -519,7 +521,7 @@
 
     /**
      * Enables or disables local heartbeat.
-     * if <code>setHeartbeat(true)</code> is invoked then the channel will 
start an internal 
+     * if <code>setHeartbeat(true)</code> is invoked then the channel will 
start an internal
      * thread to invoke <code>Channel.heartbeat()</code> every 
<code>getHeartbeatSleeptime</code> milliseconds
      * @param heartbeat boolean
      */
@@ -542,7 +544,7 @@
     public boolean getHeartbeat() {
         return heartbeat;
     }
-    
+
     /**
      * Returns the sleep time in milliseconds that the internal heartbeat will
      * sleep in between invokations of <code>Channel.heartbeat()</code>
@@ -553,11 +555,11 @@
     }
 
     /**
-     * 
-     * <p>Title: Interceptor Iterator</p> 
-     * 
-     * <p>Description: An iterator to loop through the interceptors in a 
channel</p> 
-     * 
+     *
+     * <p>Title: Interceptor Iterator</p>
+     *
+     * <p>Description: An iterator to loop through the interceptors in a 
channel</p>
+     *
      * @version 1.0
      */
     public static class InterceptorIterator implements Iterator {
@@ -567,11 +569,11 @@
             this.end = end;
             this.start = start;
         }
-        
+
         public boolean hasNext() {
             return start!=null && start != end;
         }
-        
+
         public Object next() {
             Object result = null;
             if ( hasNext() ) {
@@ -580,19 +582,19 @@
             }
             return result;
         }
-        
+
         public void remove() {
             //empty operation
         }
     }
 
     /**
-     * 
-     * <p>Title: Internal heartbeat thread</p> 
-     * 
+     *
+     * <p>Title: Internal heartbeat thread</p>
+     *
      * <p>Description: if <code>Channel.getHeartbeat()==true</code> then a 
thread of this class
-     * is created</p> 
-     * 
+     * is created</p>
+     *
      * @version 1.0
      */
     public static class HeartbeatThread extends Thread {
@@ -601,7 +603,7 @@
         protected static synchronized int inc() {
             return counter++;
         }
-        
+
         protected boolean doRun = true;
         protected GroupChannel channel;
         protected long sleepTime;
@@ -617,7 +619,7 @@
             doRun = false;
             interrupt();
         }
-        
+
         public void run() {
             while (doRun) {
                 try {
@@ -631,7 +633,7 @@
             }//while
         }//run
     }//HeartbeatThread
-    
-    
+
+
 
 }

Modified: tomcat/container/tc5.5.x/modules/groupcom/to-do.txt
URL: 
http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/groupcom/to-do.txt?rev=409799&r1=409798&r2=409799&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/modules/groupcom/to-do.txt (original)
+++ tomcat/container/tc5.5.x/modules/groupcom/to-do.txt Fri May 26 19:32:21 2006
@@ -6,29 +6,29 @@
  Why is tribes unique compared to JGroups/Appia and other group comm protocols
 
  1. Uses NIO and TCP for guaranteed delivery and the ability to join large 
groups
- 
+
  2. Guarantees messages the following way
     a) TCP messaging, with a following READ for NIO to ensure non broken 
channel
     b) ACK messages from the receiver
     c) ACK after processing
-    
+
  3. Same (single) channel can handle all types of guarantees (a,b,c) at the 
same time
     and both process synchronous and asynchronous messaging.
-    This is key to support different requirements for messaging through 
+    This is key to support different requirements for messaging through
     the same channel to save system resources.
 
  4. For async messaging, errors are reported through an error handler, callback
- 
+
  5. Ability to send on multiple streams at the same time, in parallel, to 
improve performance
- 
+
  6. Designed with replication in mind, that some pieces of data don't need to 
be totally ordered.
- 
+
  7. Its not built with the uniform group model in mind, but it can be 
accomplished using interceptors.
- 
+
  8. Future version will have WAN membership and replication
- 
+
  9. Silent members, the ability to send messages to a node not in the 
membership
- 
+
 10. Sender burst, concurrent messaging between two or more nodes
 
 11. Multicasting can still be done on a per message basis using a 
MulticastInterceptor
@@ -36,18 +36,23 @@
 Bugs:
 ===========================================
  a) Somehow the first NIO connection made, always closes down, why
- 
+
  b) pull the network cord and watch the membership layer freak out
- 
+
 Code Tasks:
 ===========================================
+50. On top of versioning, implement version syncs from primary to backup
+    Or when a backup receives an update that is out of sync
+
+49. Implement versioning on the AbstractReplicatedMap
+
 
 9. CoordinatorInterceptor - manages the selection of a cluster coordinator
    just had a brilliant idea, if GroupChannel keeps its own view of members,
    the coordinator interceptor can hold on to the member added/disappared event
    It can also intercept down going messages if the coordinator disappeared
    while a new coordinator is chosen
-   It can also intercept down going messages for members disappeared that the 
+   It can also intercept down going messages for members disappeared that the
    calling app not yet knows about, to avoid a ChannelException
    The coordinator is needed because of the mixup when two channels startup 
instantly
 
@@ -61,7 +66,7 @@
 
 36. UDP Sender and Receiver, initially without flow control and guaranteed 
delivery.
     This can be easily done as an interceptor, and operate in parallel with 
the TCP sender.
-    It can implement an auto detect, so that if the message is going to a 
destination in the same network 
+    It can implement an auto detect, so that if the message is going to a 
destination in the same network
     patch, then send it over UDP.
 
 35. The ability to share one channel amongst multiple processes
@@ -75,8 +80,8 @@
 
 30. CookieBasedReplicationMap - a very simple extension to the 
LazyReplicatedMap
     but instead of randomly selecting a backup node and then publishing the 
PROXY to all
-    the other nodes in the group, this will simply 
-    read/write a cookie, for a backup location, so the nodes will 
+    the other nodes in the group, this will simply
+    read/write a cookie, for a backup location, so the nodes will
     never know until the request comes in.
     This is useful in extremely large clusters, and essentially reduces
     very much of the network chatter, this task is dependent on task25
@@ -94,14 +99,14 @@
 
 27. XmlConfigurator - read an XML file to configure the channel.
 
-26. JNDIChannel - a way to bind the group channel in a JNDI tree, 
+26. JNDIChannel - a way to bind the group channel in a JNDI tree,
     so that shared resources can access it.
 
 23. TotalOrderInterceptor - fairly straight forward implementation
-    This interceptor would depend on the fact that there is some sort of 
+    This interceptor would depend on the fact that there is some sort of
     membership coordinator, see task 9.
-    Once there is a coordinator in the group, the total order protocol is the 
same 
-    as the OrderInterceptor, except that it gets its message number from 
+    Once there is a coordinator in the group, the total order protocol is the 
same
+    as the OrderInterceptor, except that it gets its message number from
     the coordinator, prior to sending it out.
     The TotalOrderInterceptor, will keep a order number per member,
     this way, ordering is kept intact when different messages are sent
@@ -128,7 +133,7 @@
       NOTES! THIS CANT BE DONE USING A SEQUENCER THAT SENDS THE MESSAGE SINCE 
WE
       LOSE THE ABILITY TO REPORT FEEDBACK
 
-21. Implement a WAN membership layer, using a WANMbrInterceptor and a 
+21. Implement a WAN membership layer, using a WANMbrInterceptor and a
     WAN Router/Forwarder (Tipi on top of a ManagedChannel)
 
 20. Implement a TCP membership interceptor, for guaranteed functionality, not 
just discovery
@@ -143,15 +148,15 @@
 11. Code a ReplicatedFileSystem example, package org.apache.catalina.tipis
 
 13. StateTransfer interceptor
-    the ideas just come up in my head. the state transfer interceptor 
+    the ideas just come up in my head. the state transfer interceptor
     will hold all incoming messages until it has received a message
     with a STATE_TRANSFER header as the first of the bytes.
     Once it has received state, it will pretty much take itself out of the loop
     The benefit of the new ParallelNioSender is that it doesn't require to 
know about
     a member to transfer state, all it has to do is to reply to a message that 
came in.
-    State is a one time deal for the entire channel, so a 
+    State is a one time deal for the entire channel, so a
     session replication cluster, would transfer state as one block, not one 
per context
-    
+
 14. Keepalive count and idle kill off for Nio senders
 
 17. Implement transactions - the ability to start a transaction, send several 
messages,
@@ -160,12 +165,12 @@
 Tasks Completed
 ===========================================
 1. True synchronized/asynchronized replication enabled using flags
-Sender.sendAck/Receiver.waitForAck/Receiver.synchronized 
+Sender.sendAck/Receiver.waitForAck/Receiver.synchronized
 Task Desc: waitForAck - should only mean, we received the message, not for the
 message to get processesed. This should improve throughput, and an interceptor
 can do waitForCompletion
 Status: Complete
-Notes: 
+Notes:
 
 2. Unique id, send it in byte array instead of string
 
@@ -176,7 +181,7 @@
 4. ChannelMessage.getMessage should return streamable, that way we can wrap,
 pass it around and all those good things without having to copy byte arrays
 left and right
-Notes: Instead of using a streamable, this is implemented using the 
XByteBuffer, 
+Notes: Instead of using a streamable, this is implemented using the 
XByteBuffer,
        which is very easy to use. It also becomes a single spot for 
optimizations.
        Ideally, there would be a pool of XByteBuffers, that all use direct 
ByteBuffers
        for its data handling.
@@ -200,9 +205,9 @@
     The lazy hash map will only replicate its attribute names to all members 
in the group
     with that name, it will also replicate the source (where to get the object)
     and the backup member where it can find a backup if the source is gone.
-    If the source disappears, the backup node will replicate attributes that 
+    If the source disappears, the backup node will replicate attributes that
     are stored to a new primary backups can be chosen on round robin.
-    When a new member arrives and requests state, that member will get all the 
attribute 
+    When a new member arrives and requests state, that member will get all the 
attribute
     names and the locations.
     It can replicate every X seconds, or on dirty flags by the objects stored,
     or a request to scan for dirty flags, or a request with the objects.
@@ -216,7 +221,7 @@
 
 24. MessageDispatchInterceptor - for asynchronous sending
     - looks at the options flag SEND_OPTIONS_ASYNCHRONOUS
-    - has two modes 
+    - has two modes
       a) async parallel send - each message to all destinations before next 
message
       b) async per/member - one thread per member using the FastAsyncQueue 
(good for groups with slow receivers)
     - Callback error handler - for when messages fail, and the application 
wishes to become notified
@@ -226,16 +231,16 @@
        Deep cloning is configurable as optimization.
 
 37. Interceptor.getOptionFlag() - lets the system configure a flag to be used
-    for the interceptor. that way, all constants don't have to be configured 
+    for the interceptor. that way, all constants don't have to be configured
     in Channel.SEND_FLAG_XXXX.
-    Also, the GroupChannel will make a conflict check upon startup, 
+    Also, the GroupChannel will make a conflict check upon startup,
     so that there is no conflict. I will change options to a long,
     so that we can have 63 flags, hence up to 60 interceptors.
 Notes: Completed, remained an int, so 31 flags
 
  b) State synchronization for the map - will need to add in MSG_INIT
  Fixed map bug
- 
+
  c) RpcChannel - collect "no reply" replies, so that we don't have to time out
 The RpcChannel now works together with the group channel, so that when it 
receives an RPC message
 and no one accepts it, then it can reply immediately. this way the rpc sender 
doesn't have to time out.
@@ -244,14 +249,14 @@
 Notes: Completed. The membership now carries a variable length host address to 
support IPv6
 
 40. channel.stop() - should broadcast a stop message, to avoid timeout
-Notes: Completed. 
+Notes: Completed.
 
 42. When the option SEND_OPTIONS_SYNCHRONIZED_ACK, and an error happens during
-    processing on the remote node, a FAIL_ACK command should be sent 
+    processing on the remote node, a FAIL_ACK command should be sent
     so that the sending node doesn't have to time out
-Notes: Completed. The error will be wrapped in a ChannelException and marked 
as a 
+Notes: Completed. The error will be wrapped in a ChannelException and marked 
as a
        RemoteProcessException for that node.
-       To receive this exception, one must turn on 
+       To receive this exception, one must turn on
 
 43. Silent member, node discovery.
     Add in the ability to start up tribes, but don't start the membership 
broadcast
@@ -269,9 +274,9 @@
     2. everytime a message is received, update the last check time for that
        member so that we don't need the thread to actively check
     3. when the thread wakes up, it will check maps that are outside
-       the valid range for check time, 
+       the valid range for check time,
     4. send a RPC message, if no reply, remove the map from itself
-    Other solution, use the TcpFailureDetector, catch send errors 
+    Other solution, use the TcpFailureDetector, catch send errors
 Notes: Implemented using a periodic ping in the AbstractReplicatedMap
 
 45. McastServiceImpl.receive should have a SO_TIMEOUT so that we can check
@@ -292,7 +297,7 @@
     Meaning, that all receivers get it, then wait for a process command.
     ala Gossip protocol - this is fairly redundant with a 
Xa2PhaseCommitInterceptor
     except it doesn't keep a transaction log.
-Notes: Completed in another task    
+Notes: Completed in another task
 
 10. Xa2PhaseCommitInterceptor - make sure the message doesn't reach the 
receiver unless all members got it
 Notes: Completed
@@ -302,4 +307,4 @@
 Notes: Completed
 
 19. Implement a hardcoded tcp membership
-Notes: Completed
\ No newline at end of file
+Notes: Completed



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to