/** * @param destination Member[] - destination.length > 0 * @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 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 UniqueIdRemoteInterface send( Member[] destination, Serializable msg, int options, ErrorHandler handler) throws ChannelException, RemoteException, RemoteException { if (msg == null) throw new ChannelException("Cant send a NULL message"); XByteBufferRemoteInterface buffer = null; try { if (destination == null || destination.length == 0) throw new ChannelException("No destination given"); ChannelDataRemoteInterface data = gerenciadornuvem1.getChannelData(true); // generates a unique Id data.setAddress(getLocalMember(false)); data.setTimestamp(System.currentTimeMillis()); byte[] b = null; if (msg instanceof ByteMessageRemoteInterface) { b = ((ByteMessageRemoteInterface) msg).getMessage(); options = options | SEND_OPTIONS_BYTE_MESSAGE; } else { b = gerenciadornuvem1.XByteBufferserialize(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); InterceptorPayloadRemoteInterface payload = null; if (handler != null) { payload = gerenciadornuvem0.getInterceptorPayload(); payload.setErrorHandler(handler); } getFirstInterceptor().sendMessage(destination, data, payload); if (Logs.getMessages().isTraceEnabled()) { Logs.getMessages() .trace( "GroupChannel - Sent msg:" + new UniqueId(data.getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()) + " to " + Arrays.toNameString(destination)); Logs.getMessages() .trace( "GroupChannel - Send Message:" + new UniqueId(data.getUniqueId()) + " is " + msg); } return gerenciadornuvem1.getUniqueId(data.getUniqueId()); } catch (Exception x) { if (x instanceof ChannelException) throw (ChannelException) x; throw new ChannelException(x); } finally { if (buffer != null) BufferPool.getBufferPool().returnBuffer(buffer); } }
/** * 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) throws RemoteException, RemoteException { if (msg == null) return; try { if (Logs.getMessages().isTraceEnabled()) { Logs.getMessages() .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 = gerenciadornuvem0.getByteMessage(msg.getMessage().getBytes()); } else { try { fwd = gerenciadornuvem1.XByteBufferdeserialize( msg.getMessage().getBytesDirect(), 0, msg.getMessage().getLength()); } catch (Exception sx) { log.error("Unable to deserialize message:" + msg, sx); return; } } if (Logs.getMessages().isTraceEnabled()) { Logs.getMessages() .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 RpcChannelRemoteInterface) rx = true; } } // for if ((!rx) && (fwd instanceof RpcMessageRemoteInterface)) { // if we have a message that requires a response, // but none was given, send back an immediate one sendNoRpcChannelReply((RpcMessageRemoteInterface) fwd, source); } if (Logs.getMessages().isTraceEnabled()) { Logs.getMessages() .trace( "GroupChannel delivered[" + delivered + "] id:" + new UniqueId(msg.getUniqueId())); } } catch (Exception x) { // this could be the channel listener throwing an exception, we should log it // as a warning. if (log.isWarnEnabled()) log.warn("Error receiving message:", x); throw new RemoteProcessException("Exception:" + x.getMessage(), x); } }
public int doLoop(long selectTimeOut, int maxAttempts, boolean waitForAck, ChannelMessage msg) throws IOException, ChannelException, RemoteException { try { int completed = 0; int selectedKeys = selector.select(selectTimeOut); if (selectedKeys == 0) { return 0; } Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey sk = it.next(); it.remove(); int readyOps = sk.readyOps(); sk.interestOps(sk.interestOps() & ~readyOps); org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface sender = (org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface) sk.attachment(); try { if (sender.process(sk, waitForAck)) { completed++; sender.setComplete(true); if (Logs.getMessages().isTraceEnabled()) { Logs.getMessages() .trace( "ParallelNioSender - Sent msg:" + new UniqueId(msg.getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()) + " to " + sender.getDestination().getName()); } SenderState.getSenderState(sender.getDestination()).setReady(); } // end if } catch (Exception x) { if (log.isTraceEnabled()) { log.trace("Error while processing send to " + sender.getDestination().getName(), x); } org.apache.catalina.tribes.transport.SenderStateRemoteInterface state = gerenciadornuvem0.SenderStategetSenderState(sender.getDestination()); int attempt = sender.getAttempt() + 1; boolean retry = (sender.getAttempt() <= maxAttempts && maxAttempts > 0); synchronized (state) { // sk.cancel(); if (state.isSuspect()) state.setFailing(); if (state.isReady()) { state.setSuspect(); if (retry) log.warn( "Member send is failing for:" + sender.getDestination().getName() + " ; Setting to suspect and retrying."); else log.warn( "Member send is failing for:" + sender.getDestination().getName() + " ; Setting to suspect.", x); } } if (!isConnected()) { log.warn( "Not retrying send for:" + sender.getDestination().getName() + "; Sender is disconnected."); ChannelException cx = gerenciadornuvem1.getChannelException( "Send failed, and sender is disconnected. Not retrying.", x); cx.addFaultyMember(sender.getDestination(), x); throw cx; } byte[] data = sender.getMessage(); if (retry) { try { sender.disconnect(); sender.connect(); sender.setAttempt(attempt); sender.setMessage(data); } catch (Exception ignore) { state.setFailing(); } } else { ChannelException cx = gerenciadornuvem1.getChannelException( "Send failed, attempt:" + sender.getAttempt() + " max:" + maxAttempts, x); cx.addFaultyMember(sender.getDestination(), x); throw cx; } // end if } } return completed; } catch (Exception excp) { excp.printStackTrace(); } return 0; }