Methods Summary |
---|
public void | addChannelListener(org.apache.catalina.tribes.ChannelListener channelListener)Adds a channel listener to the channel.
Channel listeners are uniquely identified using the equals(Object) method
if (!this.channelListeners.contains(channelListener) ) {
this.channelListeners.add(channelListener);
} else {
throw new IllegalArgumentException("Listener already exists:"+channelListener+"["+channelListener.getClass().getName()+"]");
}
|
public void | addInterceptor(org.apache.catalina.tribes.ChannelInterceptor interceptor)Adds an interceptor to the stack for message processing
Interceptors are ordered in the way they are added.
channel.addInterceptor(A);
channel.addInterceptor(C);
channel.addInterceptor(B);
Will result in a interceptor stack like this:
A -> C -> B
The complete stack will look like this:
Channel -> A -> C -> B -> ChannelCoordinator
if ( interceptors == null ) {
interceptors = interceptor;
interceptors.setNext(coordinator);
interceptors.setPrevious(null);
coordinator.setPrevious(interceptors);
} else {
ChannelInterceptor last = interceptors;
while ( last.getNext() != coordinator ) {
last = last.getNext();
}
last.setNext(interceptor);
interceptor.setNext(coordinator);
interceptor.setPrevious(last);
coordinator.setPrevious(interceptor);
}
|
public void | addMembershipListener(org.apache.catalina.tribes.MembershipListener membershipListener)Adds a membership listener to the channel.
Membership listeners are uniquely identified using the equals(Object) method
if (!this.membershipListeners.contains(membershipListener) )
this.membershipListeners.add(membershipListener);
|
protected void | checkOptionFlags()Validates the option flags that each interceptor is using and reports
an error if two interceptor share the same flag.
StringBuffer conflicts = new StringBuffer();
ChannelInterceptor first = interceptors;
while ( first != null ) {
int flag = first.getOptionFlag();
if ( flag != 0 ) {
ChannelInterceptor next = first.getNext();
while ( next != null ) {
int nflag = next.getOptionFlag();
if (nflag!=0 && (((flag & nflag) == flag ) || ((flag & nflag) == nflag)) ) {
conflicts.append("[");
conflicts.append(first.getClass().getName());
conflicts.append(":");
conflicts.append(flag);
conflicts.append(" == ");
conflicts.append(next.getClass().getName());
conflicts.append(":");
conflicts.append(nflag);
conflicts.append("] ");
}//end if
next = next.getNext();
}//while
}//end if
first = first.getNext();
}//while
if ( conflicts.length() > 0 ) throw new ChannelException("Interceptor option flag conflict: "+conflicts.toString());
|
public org.apache.catalina.tribes.ChannelReceiver | getChannelReceiver()Returns the channel receiver component
return coordinator.getClusterReceiver();
|
public org.apache.catalina.tribes.ChannelSender | getChannelSender()Returns the channel sender component
return coordinator.getClusterSender();
|
public org.apache.catalina.tribes.ChannelInterceptor | getFirstInterceptor()Returns the first interceptor of the stack. Useful for traversal.
if (interceptors != null) return interceptors;
else return coordinator;
|
public boolean | getHeartbeat()
return heartbeat;
|
public long | getHeartbeatSleeptime()Returns the sleep time in milliseconds that the internal heartbeat will
sleep in between invokations of Channel.heartbeat()
return heartbeatSleeptime;
|
public java.util.Iterator | getInterceptors()Returns an iterator of all the interceptors in this stack
return new InterceptorIterator(this.getNext(),this.coordinator);
|
public org.apache.catalina.tribes.MembershipService | getMembershipService()Returns the membership service component
return coordinator.getMembershipService();
|
public boolean | getOptionCheck()
return optionCheck;
|
public void | heartbeat()Sends a heartbeat through the interceptor stack.
Invoke this method from the application on a periodic basis if
you have turned off internal heartbeats channel.setHeartbeat(false)
super.heartbeat();
Iterator i = membershipListeners.iterator();
while ( i.hasNext() ) {
Object o = i.next();
if ( o instanceof Heartbeat ) ((Heartbeat)o).heartbeat();
}
i = channelListeners.iterator();
while ( i.hasNext() ) {
Object o = i.next();
if ( o instanceof Heartbeat ) ((Heartbeat)o).heartbeat();
}
|
public void | memberAdded(org.apache.catalina.tribes.Member member)memberAdded gets invoked by the interceptor below the channel
and the channel will broadcast it to the membership listeners
//notify upwards
for (int i=0; i<membershipListeners.size(); i++ ) {
MembershipListener membershipListener = (MembershipListener)membershipListeners.get(i);
if (membershipListener != null) membershipListener.memberAdded(member);
}
|
public void | memberDisappeared(org.apache.catalina.tribes.Member member)memberDisappeared gets invoked by the interceptor below the channel
and the channel will broadcast it to the membership listeners
//notify upwards
for (int i=0; i<membershipListeners.size(); i++ ) {
MembershipListener membershipListener = (MembershipListener)membershipListeners.get(i);
if (membershipListener != null) membershipListener.memberDisappeared(member);
}
|
public void | messageReceived(org.apache.catalina.tribes.ChannelMessage msg)Callback from the interceptor stack.
When a message is received from a remote node, this method will be invoked by
the previous interceptor.
This method can also be used to send a message to other components within the same application,
but its an extreme case, and you're probably better off doing that logic between the applications itself.
if ( msg == null ) return;
try {
if ( Logs.MESSAGES.isTraceEnabled() ) {
Logs.MESSAGES.trace("GroupChannel - Received msg:" + new UniqueId(msg.getUniqueId()) + " at " +new java.sql.Timestamp(System.currentTimeMillis())+ " from "+msg.getAddress().getName());
}
Serializable fwd = null;
if ( (msg.getOptions() & SEND_OPTIONS_BYTE_MESSAGE) == SEND_OPTIONS_BYTE_MESSAGE ) {
fwd = new ByteMessage(msg.getMessage().getBytes());
} else {
fwd = XByteBuffer.deserialize(msg.getMessage().getBytesDirect(),0,msg.getMessage().getLength());
}
if ( Logs.MESSAGES.isTraceEnabled() ) {
Logs.MESSAGES.trace("GroupChannel - Receive Message:" + new UniqueId(msg.getUniqueId()) + " is " +fwd);
}
//get the actual member with the correct alive time
Member source = msg.getAddress();
boolean rx = false;
boolean delivered = false;
for ( int i=0; i<channelListeners.size(); i++ ) {
ChannelListener channelListener = (ChannelListener)channelListeners.get(i);
if (channelListener != null && channelListener.accept(fwd, source)) {
channelListener.messageReceived(fwd, source);
delivered = 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)) {
//if we have a message that requires a response,
//but none was given, send back an immediate one
sendNoRpcChannelReply((RpcMessage)fwd,source);
}
if ( Logs.MESSAGES.isTraceEnabled() ) {
Logs.MESSAGES.trace("GroupChannel delivered["+delivered+"] id:"+new UniqueId(msg.getUniqueId()));
}
} catch ( Exception x ) {
if ( log.isDebugEnabled() ) log.error("Unable to process channel:IOException.",x);
throw new RemoteProcessException("IOException:"+x.getMessage(),x);
}
|
public void | removeChannelListener(org.apache.catalina.tribes.ChannelListener channelListener)Removes a channel listener from the channel.
Channel listeners are uniquely identified using the equals(Object) method
channelListeners.remove(channelListener);
|
public void | removeMembershipListener(org.apache.catalina.tribes.MembershipListener membershipListener)Removes a membership listener from the channel.
Membership listeners are uniquely identified using the equals(Object) method
membershipListeners.remove(membershipListener);
|
public org.apache.catalina.tribes.UniqueId | send(org.apache.catalina.tribes.Member[] destination, java.io.Serializable msg, int options)Send a message to the destinations specified
return send(destination,msg,options,null);
|
public org.apache.catalina.tribes.UniqueId | send(org.apache.catalina.tribes.Member[] destination, java.io.Serializable msg, int options, org.apache.catalina.tribes.ErrorHandler handler)
if ( msg == null ) throw new ChannelException("Cant send a NULL message");
XByteBuffer buffer = null;
try {
if ( destination == null || destination.length == 0) throw new ChannelException("No destination given");
ChannelData data = new ChannelData(true);//generates a unique Id
data.setAddress(getLocalMember(false));
data.setTimestamp(System.currentTimeMillis());
byte[] b = null;
if ( msg instanceof ByteMessage ){
b = ((ByteMessage)msg).getMessage();
options = options | SEND_OPTIONS_BYTE_MESSAGE;
} else {
b = XByteBuffer.serialize(msg);
options = options & (~SEND_OPTIONS_BYTE_MESSAGE);
}
data.setOptions(options);
//XByteBuffer buffer = new XByteBuffer(b.length+128,false);
buffer = BufferPool.getBufferPool().getBuffer(b.length+128, false);
buffer.append(b,0,b.length);
data.setMessage(buffer);
InterceptorPayload payload = null;
if ( handler != null ) {
payload = new InterceptorPayload();
payload.setErrorHandler(handler);
}
getFirstInterceptor().sendMessage(destination, data, payload);
if ( Logs.MESSAGES.isTraceEnabled() ) {
Logs.MESSAGES.trace("GroupChannel - Sent msg:" + new UniqueId(data.getUniqueId()) + " at " +new java.sql.Timestamp(System.currentTimeMillis())+ " to "+Arrays.toNameString(destination));
Logs.MESSAGES.trace("GroupChannel - Send Message:" + new UniqueId(data.getUniqueId()) + " is " +msg);
}
return new UniqueId(data.getUniqueId());
}catch ( Exception x ) {
if ( x instanceof ChannelException ) throw (ChannelException)x;
throw new ChannelException(x);
} finally {
if ( buffer != null ) BufferPool.getBufferPool().returnBuffer(buffer);
}
|
protected void | sendNoRpcChannelReply(RpcMessage msg, org.apache.catalina.tribes.Member destination)Sends a NoRpcChannelReply message to a member
This method gets invoked by the channel if a RPC message comes in
and no channel listener accepts the message. This avoids timeout
try {
//avoid circular loop
if ( msg instanceof RpcMessage.NoRpcChannelReply) return;
RpcMessage.NoRpcChannelReply reply = new RpcMessage.NoRpcChannelReply(msg.rpcId,msg.uuid);
send(new Member[]{destination},reply,Channel.SEND_OPTIONS_ASYNCHRONOUS);
} catch ( Exception x ) {
log.error("Unable to find rpc channel, failed to send NoRpcChannelReply.",x);
}
|
public void | setChannelReceiver(org.apache.catalina.tribes.ChannelReceiver clusterReceiver)Sets the channel receiver component
coordinator.setClusterReceiver(clusterReceiver);
|
public void | setChannelSender(org.apache.catalina.tribes.ChannelSender clusterSender)Sets the channel sender component
coordinator.setClusterSender(clusterSender);
|
public void | setHeartbeat(boolean heartbeat)Enables or disables local heartbeat.
if setHeartbeat(true) is invoked then the channel will start an internal
thread to invoke Channel.heartbeat() every getHeartbeatSleeptime milliseconds
this.heartbeat = heartbeat;
|
public void | setHeartbeatSleeptime(long heartbeatSleeptime)Configure local heartbeat sleep time
Only used when getHeartbeat()==true
this.heartbeatSleeptime = heartbeatSleeptime;
|
public void | setMembershipService(org.apache.catalina.tribes.MembershipService membershipService)Sets the membership component
coordinator.setMembershipService(membershipService);
|
public void | setOptionCheck(boolean optionCheck)Enables/disables the option check
Setting this to true, will make the GroupChannel perform a conflict check
on the interceptors. If two interceptors are using the same option flag
and throw an error upon start.
this.optionCheck = optionCheck;
|
protected synchronized void | setupDefaultStack()Sets up the default implementation interceptor stack
if no interceptors have been added
if ( getFirstInterceptor() != null &&
((getFirstInterceptor().getNext() instanceof ChannelCoordinator))) {
ChannelInterceptor interceptor = null;
Class clazz = null;
try {
clazz = Class.forName("org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor",
true,GroupChannel.class.getClassLoader());
clazz.newInstance();
} catch ( Throwable x ) {
clazz = MessageDispatchInterceptor.class;
}//catch
try {
interceptor = (ChannelInterceptor) clazz.newInstance();
} catch (Exception x) {
throw new ChannelException("Unable to add MessageDispatchInterceptor to interceptor chain.",x);
}
this.addInterceptor(interceptor);
}
|
public synchronized void | start(int svc)Starts the channel
setupDefaultStack();
if (optionCheck) checkOptionFlags();
super.start(svc);
if ( hbthread == null && heartbeat ) {
hbthread = new HeartbeatThread(this,heartbeatSleeptime);
hbthread.start();
}
|
public synchronized void | stop(int svc)Stops the channel
if (hbthread != null) {
hbthread.stopHeartbeat();
hbthread = null;
}
super.stop(svc);
|