heartbeat == true then how often do we want this
* heartbeat to run. default is one minute
*/
protected long heartbeatSleeptime = 5*1000;//every 5 seconds
/**
* Internal heartbeat thread
*/
protected HeartbeatThread hbthread = null;
/**
* The ChannelCoordinator coordinates the bottom layer components:channel.addInterceptor(A);channel.addInterceptor(C);channel.addInterceptor(B);A -> C -> BChannel -> A -> C -> B -> ChannelCoordinatorchannel.setHeartbeat(false)
*/
@Override
public void heartbeat() {
super.heartbeat();
for (MembershipListener listener : membershipListeners) {
if ( listener instanceof Heartbeat ) ((Heartbeat)listener).heartbeat();
}
for (ChannelListener listener : channelListeners) {
if ( listener instanceof Heartbeat ) ((Heartbeat)listener).heartbeat();
}
}
/**
* Send a message to the destinations specified
* @param destination Member[] - destination.length > 0
* @param msg Serializable - the message to send
* @param options sender options, options can trigger guarantee levels and different
* interceptors to react to the message see class documentation for the
* Channel object.Channel object.Channel.SEND_OPTIONS_ASYNCHRONOUS flag enabled.
* @return UniqueId - the unique Id that was assigned to this message
* @throws ChannelException - if an error occurs processing the message
* @see org.apache.catalina.tribes.Channel
*/
@Override
public UniqueId send(Member[] destination, Serializable msg, int options, ErrorHandler handler)
throws ChannelException {
if ( msg == null ) throw new ChannelException(sm.getString("groupChannel.nullMessage"));
XByteBuffer buffer = null;
try {
if (destination == null || destination.length == 0) {
throw new ChannelException(sm.getString("groupChannel.noDestination"));
}
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 (RuntimeException | IOException e) {
throw new ChannelException(e);
} finally {
if ( buffer != null ) BufferPool.getBufferPool().returnBuffer(buffer);
}
}
/**
* Callback from the interceptor stack. getHeartbeat()==true
* @param heartbeatSleeptime long - time in milliseconds to sleep between heartbeats
*/
public void setHeartbeatSleeptime(long heartbeatSleeptime) {
this.heartbeatSleeptime = heartbeatSleeptime;
}
/**
* 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
* @param heartbeat boolean
*/
@Override
public void setHeartbeat(boolean heartbeat) {
this.heartbeat = heartbeat;
}
/**
* @see #setOptionCheck(boolean)
* @return boolean
*/
@Override
public boolean getOptionCheck() {
return optionCheck;
}
/**
* @see #setHeartbeat(boolean)
* @return boolean
*/
@Override
public boolean getHeartbeat() {
return heartbeat;
}
/**
* Returns the sleep time in milliseconds that the internal heartbeat will
* sleep in between invocations of Channel.heartbeat()
* @return long
*/
@Override
public long getHeartbeatSleeptime() {
return heartbeatSleeptime;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public boolean isJmxEnabled() {
return jmxEnabled;
}
@Override
public void setJmxEnabled(boolean jmxEnabled) {
this.jmxEnabled = jmxEnabled;
}
@Override
public String getJmxDomain() {
return jmxDomain;
}
@Override
public void setJmxDomain(String jmxDomain) {
this.jmxDomain = jmxDomain;
}
@Override
public String getJmxPrefix() {
return jmxPrefix;
}
@Override
public void setJmxPrefix(String jmxPrefix) {
this.jmxPrefix = jmxPrefix;
}
@Override
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
// NOOP
return null;
}
@Override
public void postRegister(Boolean registrationDone) {
// NOOP
}
@Override
public void preDeregister() throws Exception {
// NOOP
}
@Override
public void postDeregister() {
JmxRegistry.removeRegistry(this, true);
}
/**
*
* Title: Interceptor Iterator
* *Description: An iterator to loop through the interceptors in a channel
* * @version 1.0 */ public static class InterceptorIterator implements IteratorTitle: Internal heartbeat thread
* *Description: if Channel.getHeartbeat()==true then a thread of this class
* is created