use of org.apache.catalina.tribes.RemoteProcessException in project tomcat70 by apache.
the class NioReplicationTask method drainChannel.
/**
* The actual code which drains the channel associated with
* the given key. This method assumes the key has been
* modified prior to invocation to turn off selection
* interest in OP_READ. When this method completes it
* re-enables OP_READ and calls wakeup() on the selector
* so the selector will resume watching this channel.
*/
protected void drainChannel(final SelectionKey key, ObjectReader reader) throws Exception {
reader.setLastAccess(System.currentTimeMillis());
reader.access();
ReadableByteChannel channel = (ReadableByteChannel) key.channel();
int count = -1;
// make buffer empty
buffer.clear();
SocketAddress saddr = null;
if (channel instanceof SocketChannel) {
// loop while data available, channel is non-blocking
while ((count = channel.read(buffer)) > 0) {
// make buffer readable
buffer.flip();
if (buffer.hasArray())
reader.append(buffer.array(), 0, count, false);
else
reader.append(buffer, count, false);
// make buffer empty
buffer.clear();
// do we have at least one package?
if (reader.hasPackage())
break;
}
} else if (channel instanceof DatagramChannel) {
DatagramChannel dchannel = (DatagramChannel) channel;
saddr = dchannel.receive(buffer);
// make buffer readable
buffer.flip();
if (buffer.hasArray())
reader.append(buffer.array(), 0, buffer.limit() - buffer.position(), false);
else
reader.append(buffer, buffer.limit() - buffer.position(), false);
// make buffer empty
buffer.clear();
// did we get a package
count = reader.hasPackage() ? 1 : -1;
}
int pkgcnt = reader.count();
if (count < 0 && pkgcnt == 0) {
// end of stream, and no more packages to process
remoteEof(key);
return;
}
ChannelMessage[] msgs = pkgcnt == 0 ? ChannelData.EMPTY_DATA_ARRAY : reader.execute();
// register to read new data, before we send it off to avoid dead locks
registerForRead(key, reader);
for (int i = 0; i < msgs.length; i++) {
/**
* Use send ack here if you want to ack the request to the remote
* server before completing the request
* This is considered an asynchronous request
*/
if (ChannelData.sendAckAsync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
try {
if (Logs.MESSAGES.isTraceEnabled()) {
try {
Logs.MESSAGES.trace("NioReplicationThread - Received msg:" + new UniqueId(msgs[i].getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()));
} catch (Throwable t) {
}
}
// process the message
getCallback().messageDataReceived(msgs[i]);
/**
* Use send ack here if you want the request to complete on this
* server before sending the ack to the remote server
* This is considered a synchronized request
*/
if (ChannelData.sendAckSync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
} catch (RemoteProcessException e) {
if (log.isDebugEnabled())
log.error("Processing of cluster message failed.", e);
if (ChannelData.sendAckSync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
} catch (Exception e) {
log.error("Processing of cluster message failed.", e);
if (ChannelData.sendAckSync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
}
if (getUseBufferPool()) {
BufferPool.getBufferPool().returnBuffer(msgs[i].getMessage());
msgs[i].setMessage(null);
}
}
if (count < 0) {
remoteEof(key);
return;
}
}
use of org.apache.catalina.tribes.RemoteProcessException in project tomcat70 by apache.
the class GroupChannel method messageReceived.
/**
* Callback from the interceptor stack. <br>
* When a message is received from a remote node, this method will be invoked by
* the previous interceptor.<br>
* 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.
* @param msg ChannelMessage
*/
@Override
public void messageReceived(ChannelMessage msg) {
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 {
try {
fwd = XByteBuffer.deserialize(msg.getMessage().getBytesDirect(), 0, msg.getMessage().getLength());
} catch (Exception sx) {
log.error("Unable to deserialize message:" + msg, sx);
return;
}
}
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;
// 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) {
// as a warning.
if (log.isWarnEnabled())
log.warn("Error receiving message:", x);
throw new RemoteProcessException("Exception:" + x.getMessage(), x);
}
}
use of org.apache.catalina.tribes.RemoteProcessException in project tomcat70 by apache.
the class BioSender method waitForAck.
/**
* Wait for Acknowledgement from other server.
* FIXME Please, not wait only for three characters, better control that the wait ack message is correct.
* @throws java.io.IOException
* @throws java.net.SocketTimeoutException
*/
protected void waitForAck() throws java.io.IOException {
try {
boolean ackReceived = false;
boolean failAckReceived = false;
ackbuf.clear();
int bytesRead = 0;
int i = soIn.read();
while ((i != -1) && (bytesRead < Constants.ACK_COMMAND.length)) {
bytesRead++;
byte d = (byte) i;
ackbuf.append(d);
if (ackbuf.doesPackageExist()) {
byte[] ackcmd = ackbuf.extractDataPackage(true).getBytes();
ackReceived = Arrays.equals(ackcmd, org.apache.catalina.tribes.transport.Constants.ACK_DATA);
failAckReceived = Arrays.equals(ackcmd, org.apache.catalina.tribes.transport.Constants.FAIL_ACK_DATA);
ackReceived = ackReceived || failAckReceived;
break;
}
i = soIn.read();
}
if (!ackReceived) {
if (i == -1)
throw new IOException(sm.getString("IDataSender.ack.eof", getAddress(), Integer.valueOf(socket.getLocalPort())));
else
throw new IOException(sm.getString("IDataSender.ack.wrong", getAddress(), Integer.valueOf(socket.getLocalPort())));
} else if (failAckReceived && getThrowOnFailedAck()) {
throw new RemoteProcessException("Received a failed ack:org.apache.catalina.tribes.transport.Constants.FAIL_ACK_DATA");
}
} catch (IOException x) {
String errmsg = sm.getString("IDataSender.ack.missing", getAddress(), Integer.valueOf(socket.getLocalPort()), Long.valueOf(getTimeout()));
if (SenderState.getSenderState(getDestination()).isReady()) {
SenderState.getSenderState(getDestination()).setSuspect();
if (log.isWarnEnabled())
log.warn(errmsg, x);
} else {
if (log.isDebugEnabled())
log.debug(errmsg, x);
}
throw x;
} finally {
ackbuf.clear();
}
}
use of org.apache.catalina.tribes.RemoteProcessException in project tomcat by apache.
the class NioReplicationTask method drainChannel.
/**
* The actual code which drains the channel associated with
* the given key. This method assumes the key has been
* modified prior to invocation to turn off selection
* interest in OP_READ. When this method completes it
* re-enables OP_READ and calls wakeup() on the selector
* so the selector will resume watching this channel.
* @param key The key to process
* @param reader The reader
* @throws Exception IO error
*/
protected void drainChannel(final SelectionKey key, ObjectReader reader) throws Exception {
reader.access();
ReadableByteChannel channel = (ReadableByteChannel) key.channel();
int count = -1;
// make buffer empty
buffer.clear();
SocketAddress saddr = null;
if (channel instanceof SocketChannel) {
// loop while data available, channel is non-blocking
while ((count = channel.read(buffer)) > 0) {
// make buffer readable
buffer.flip();
if (buffer.hasArray()) {
reader.append(buffer.array(), 0, count, false);
} else {
reader.append(buffer, count, false);
}
// make buffer empty
buffer.clear();
// do we have at least one package?
if (reader.hasPackage()) {
break;
}
}
} else if (channel instanceof DatagramChannel) {
DatagramChannel dchannel = (DatagramChannel) channel;
saddr = dchannel.receive(buffer);
// make buffer readable
buffer.flip();
if (buffer.hasArray()) {
reader.append(buffer.array(), 0, buffer.limit() - buffer.position(), false);
} else {
reader.append(buffer, buffer.limit() - buffer.position(), false);
}
// make buffer empty
buffer.clear();
// did we get a package
count = reader.hasPackage() ? 1 : -1;
}
int pkgcnt = reader.count();
if (count < 0 && pkgcnt == 0) {
// end of stream, and no more packages to process
remoteEof(key);
return;
}
ChannelMessage[] msgs = pkgcnt == 0 ? ChannelData.EMPTY_DATA_ARRAY : reader.execute();
// register to read new data, before we send it off to avoid dead locks
registerForRead(key, reader);
for (ChannelMessage msg : msgs) {
/**
* Use send ack here if you want to ack the request to the remote
* server before completing the request
* This is considered an asynchronous request
*/
if (ChannelData.sendAckAsync(msg.getOptions())) {
sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
}
try {
if (Logs.MESSAGES.isTraceEnabled()) {
try {
Logs.MESSAGES.trace("NioReplicationThread - Received msg:" + new UniqueId(msg.getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()));
} catch (Throwable t) {
}
}
// process the message
getCallback().messageDataReceived(msg);
/**
* Use send ack here if you want the request to complete on this
* server before sending the ack to the remote server
* This is considered a synchronized request
*/
if (ChannelData.sendAckSync(msg.getOptions())) {
sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
}
} catch (RemoteProcessException e) {
if (log.isDebugEnabled()) {
log.error(sm.getString("nioReplicationTask.process.clusterMsg.failed"), e);
}
if (ChannelData.sendAckSync(msg.getOptions())) {
sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
}
} catch (Exception e) {
log.error(sm.getString("nioReplicationTask.process.clusterMsg.failed"), e);
if (ChannelData.sendAckSync(msg.getOptions())) {
sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
}
}
if (getUseBufferPool()) {
BufferPool.getBufferPool().returnBuffer(msg.getMessage());
msg.setMessage(null);
}
}
if (count < 0) {
remoteEof(key);
}
}
use of org.apache.catalina.tribes.RemoteProcessException in project tomcat by apache.
the class GroupChannel method messageReceived.
/**
* Callback from the interceptor stack. <br>
* When a message is received from a remote node, this method will be
* invoked by the previous interceptor.<br>
* 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.
* @param msg ChannelMessage
*/
@Override
public void messageReceived(ChannelMessage msg) {
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 {
try {
fwd = XByteBuffer.deserialize(msg.getMessage().getBytesDirect(), 0, msg.getMessage().getLength());
} catch (Exception sx) {
log.error(sm.getString("groupChannel.unable.deserialize", msg), sx);
return;
}
}
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 (ChannelListener channelListener : channelListeners) {
if (channelListener != null && channelListener.accept(fwd, source)) {
channelListener.messageReceived(fwd, source);
delivered = true;
// 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) {
// as a warning.
if (log.isWarnEnabled()) {
log.warn(sm.getString("groupChannel.receiving.error"), x);
}
throw new RemoteProcessException(sm.getString("groupChannel.receiving.error"), x);
}
}
Aggregations