// This must never called by more than one thread concurrently public boolean send(final Packet packet, final boolean flush, final boolean batch) { if (invokeInterceptors(packet, interceptors, connection) != null) { return false; } synchronized (sendLock) { packet.setChannelID(id); if (isTrace) { HornetQClientLogger.LOGGER.trace( "Sending packet nonblocking " + packet + " on channeID=" + id); } HornetQBuffer buffer = packet.encode(connection); lock.lock(); try { if (failingOver) { // TODO - don't hardcode this timeout try { failoverCondition.await(10000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { throw new HornetQInterruptedException(e); } } // Sanity check if (transferring) { throw new IllegalStateException("Cannot send a packet while channel is doing failover"); } if (resendCache != null && packet.isRequiresConfirmations()) { resendCache.add(packet); } } finally { lock.unlock(); } if (isTrace) { HornetQClientLogger.LOGGER.trace("Writing buffer for channelID=" + id); } // The actual send must be outside the lock, or with OIO transport, the write can block if the // tcp // buffer is full, preventing any incoming buffers being handled and blocking failover connection.getTransportConnection().write(buffer, flush, batch); return true; } }
public void replayCommands(final int otherLastConfirmedCommandID) { if (resendCache != null) { if (isTrace) { HornetQClientLogger.LOGGER.trace("Replaying commands on channelID=" + id); } clearUpTo(otherLastConfirmedCommandID); for (final Packet packet : resendCache) { doWrite(packet); } } }