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 >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"/>
</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]