use of com.swiftmq.amqp.v100.client.po.POSendMessage in project swiftmq-client by iitsoftware.
the class SessionDispatcher method doSend.
private void doSend(POSendMessage po) {
if (pTracer.isEnabled())
pTracer.trace(toString(), ", doSend, po=" + po + ", dataLength=" + po.getPackager().getSize());
try {
Producer producer = po.getProducer();
producer.verifyState();
Packager packager = po.getPackager();
if (remoteIncomingWindow > 0 && outgoingWindow > 0) {
do {
boolean wasFirstPacket = false;
boolean isAtMostOnce = producer.getQoS() == QoS.AT_MOST_ONCE;
packager.setMaxFrameSize(mySession.myConnection.connectionDispatcher.getMaxFrameSize());
TransferFrame frame = new TransferFrame(mySession.getChannel());
frame.setHandle(new Handle(producer.getHandle()));
frame.setSettled(new AMQPBoolean(isAtMostOnce));
if (packager.getCurrentPacketNumber() == 0) {
long dId = nextDeliveryId();
wasFirstPacket = true;
producer.incDeliveryCountSnd();
DeliveryTag deliveryTag = po.getDeliveryTag() != null ? po.getDeliveryTag() : producer.createDeliveryTag();
if (!isAtMostOnce) {
if (po.getTxnId() == null && !po.isRecovery())
producer.getDeliveryMemory().addUnsettledDelivery(new UnsettledDelivery(deliveryTag, null, po.getMessage()));
unsettledOutgoingDeliveries.put(dId, new DeliveryMapping(deliveryTag, producer));
}
frame.setDeliveryTag(deliveryTag);
frame.setDeliveryId(new DeliveryNumber(dId));
frame.setMessageFormat(new MessageFormat(0));
TxnIdIF txnId = po.getTxnId();
if (txnId != null) {
TransactionalState txState = new TransactionalState();
txState.setTxnId(txnId);
frame.setState(txState);
}
}
packager.setMessageFormat(0);
packager.getNextPacket(frame);
// We may increase the outgoing window and send a flow before
if (wasFirstPacket && outgoingWindow - packager.getPredictedNumberPackets() < 0) {
outgoingWindow += packager.getPredictedNumberPackets();
sendFlow();
windowChanged = true;
}
if (pTracer.isEnabled())
pTracer.trace(toString(), ", doSend, remoteIncomingWindows=" + remoteIncomingWindow + ", outgoingWindow=" + outgoingWindow + ", sending message, wasFirstPacket=" + wasFirstPacket + ", maxSize=" + packager.getMaxPayloadLength() + ", packetSize=" + frame.getPayload().length + ", predictedNumberPackets=" + packager.getPredictedNumberPackets() + ", currentPacket=" + packager.getCurrentPacketNumber() + ", hasMore=" + packager.hasMore());
outboundHandler.send(frame);
nextOutgoingId++;
remoteIncomingWindow--;
if (!isAtMostOnce)
outgoingWindow--;
if (!packager.hasMore()) {
// b) everything else: after the last packet has been sent
if (producer.isTransactionController() || po.getTxnId() != null)
producer.setWaitingPO(po);
else {
po.setSuccess(true);
if (po.getSemaphore() != null)
po.getSemaphore().notifySingleWaiter();
}
// If that was the last packet and outgoing window was increased for this message, we need to reset it and send another flow
if (windowChanged) {
outgoingWindow = mySession.getOutgoingWindowSize();
sendFlow();
}
break;
}
} while (remoteIncomingWindow > 0 && outgoingWindow > 0);
if (packager.hasMore()) {
if (pTracer.isEnabled())
pTracer.trace(toString(), ", doSend, remoteIncomingWindows=" + remoteIncomingWindow + ", outgoingWindow=" + outgoingWindow + ", has more but no window, storing message");
outboundDeliveries.add(po);
}
} else {
if (pTracer.isEnabled())
pTracer.trace(toString(), ", doSend, po=" + po + ", remoteIncomingWindows=" + remoteIncomingWindow + ", outgoingWindow=" + outgoingWindow + ", no window, storing message");
outboundDeliveries.add(po);
}
} catch (Exception e) {
po.setSuccess(false);
po.setException(e.getMessage());
if (po.getSemaphore() != null)
po.getSemaphore().notifySingleWaiter();
}
}
use of com.swiftmq.amqp.v100.client.po.POSendMessage in project swiftmq-client by iitsoftware.
the class SessionDispatcher method settleOutbound.
private void settleOutbound(long from, long to, boolean settled, DeliveryStateIF deliveryState) {
if (from <= to) {
long current = from;
while (current <= to) {
DeliveryMapping deliveryMapping = unsettledOutgoingDeliveries.remove(current);
if (deliveryMapping != null) {
deliveryMapping.link.getDeliveryMemory().deliverySettled(deliveryMapping.deliveryTag);
if (deliveryMapping.link.getWaitingPO() != null) {
POSendMessage po = (POSendMessage) deliveryMapping.link.getWaitingPO();
po.setSuccess(true);
po.setDeliveryState(deliveryState);
po.getSemaphore().notifySingleWaiter();
deliveryMapping.link.setWaitingPO(null);
}
// If there is a close waiting on that link, dispatch it when there are no more unsettled deliveries
if (deliveryMapping.link.getDeliveryMemory().getNumberUnsettled() == 0 && deliveryMapping.link.getWaitingClosePO() != null) {
dispatch(deliveryMapping.link.getWaitingClosePO());
deliveryMapping.link.setWaitingClosePO(null);
}
}
current++;
outgoingWindow++;
}
if (deliveryState != null) {
if (!settled && deliveryState instanceof Accepted) {
DispositionFrame dispoFrame = new DispositionFrame(mySession.getChannel());
dispoFrame.setRole(Role.SENDER);
dispoFrame.setFirst(new DeliveryNumber(from));
dispoFrame.setLast(new DeliveryNumber(to));
dispoFrame.setSettled(AMQPBoolean.TRUE);
dispoFrame.setState(new Accepted());
outboundHandler.send(dispoFrame);
}
}
} else {
// TODO: error
}
}
use of com.swiftmq.amqp.v100.client.po.POSendMessage in project swiftmq-client by iitsoftware.
the class Producer method send.
/**
* Send a message to the target. For transactional sends the method returns after settlement has been finished, otherwise when the message has been sent.
*
* @param msg message
* @param persistent whether the message should send/stored durable
* @param priority message priority (default is 5)
* @param ttl time to live (expiration) in milliseconds, default no expiration
* @return delivery state of the message
* @throws AMQPException on error
*/
public DeliveryStateIF send(AMQPMessage msg, boolean persistent, int priority, long ttl) throws AMQPException {
verifyState();
Header header = msg.getHeader();
if (header == null) {
header = new Header();
msg.setHeader(header);
}
header.setDurable(new AMQPBoolean(persistent));
header.setPriority(new AMQPUnsignedByte(priority));
if (ttl >= 0)
header.setTtl(new Milliseconds(ttl));
Properties props = msg.getProperties();
if (props == null) {
props = new Properties();
msg.setProperties(props);
}
if (props.getMessageId() == null)
props.setMessageId(new MessageIdString(nextMsgId()));
props.setTo(new AddressString(target));
String userName = mySession.myConnection.getUserName();
if (userName != null)
props.setUserId(new AMQPBinary(userName.getBytes()));
Semaphore sem = new Semaphore();
try {
POSendMessage po = new POSendMessage(sem, this, msg, msg.getTxnIdIF(), msg.getDeliveryTag());
mySession.dispatch(po);
sem.waitHere();
if (!po.isSuccess())
throw new AMQPException(po.getException());
return po.getDeliveryState();
} catch (Exception e) {
e.printStackTrace();
throw new AMQPException(e.toString());
}
}
use of com.swiftmq.amqp.v100.client.po.POSendMessage in project swiftmq-client by iitsoftware.
the class Producer method recover.
protected void recover(AMQPMap remoteUnsettled) {
try {
if (remoteUnsettled != null) {
Map<AMQPType, AMQPType> map = remoteUnsettled.getValue();
for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry = (Map.Entry) iter.next();
final DeliveryTag deliveryTag = new DeliveryTag(((AMQPBinary) entry.getKey()).getValue());
final AMQPList deliveryState = (AMQPList) entry.getValue();
if (deliveryState != null) {
try {
DeliveryStateFactory.create(deliveryState).accept(new DeliveryStateVisitorAdapter() {
public void visit(Accepted impl) {
deliveryMemory.deliverySettled(deliveryTag);
mySession.dispatch(new POSendResumedTransfer(Producer.this, deliveryTag));
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
if (deliveryMemory.getNumberUnsettled() > 0) {
Collection<UnsettledDelivery> unsettled = deliveryMemory.getUnsettled();
for (Iterator<UnsettledDelivery> iter = unsettled.iterator(); iter.hasNext(); ) {
UnsettledDelivery unsettledDelivery = iter.next();
if (unsettledDelivery.getMessage() != null) {
AMQPMessage msg = unsettledDelivery.getMessage();
if (msg.getTxnIdIF() == null) {
POSendMessage po = new POSendMessage(null, this, msg, null, unsettledDelivery.getDeliveryTag());
po.setRecovery(true);
mySession.dispatch(po);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Aggregations