/** * 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(), new Integer(socket.getLocalPort()))); else throw new IOException( sm.getString( "IDataSender.ack.wrong", getAddress(), new Integer(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(), new Integer(socket.getLocalPort()), new Long(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(); } }
/** * @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 <code>Channel</code> object.<br> * @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 * @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 (Exception x) { if (x instanceof ChannelException) throw (ChannelException) x; throw new ChannelException(x); } finally { if (buffer != null) BufferPool.getBufferPool().returnBuffer(buffer); } }