Search in sources :

Example 1 with DeliveryNumber

use of com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber 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();
    }
}
Also used : TxnIdIF(com.swiftmq.amqp.v100.generated.transactions.coordination.TxnIdIF) IOException(java.io.IOException) TransactionalState(com.swiftmq.amqp.v100.generated.transactions.coordination.TransactionalState) Packager(com.swiftmq.amqp.v100.transport.Packager)

Example 2 with DeliveryNumber

use of com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber 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
    }
}
Also used : Accepted(com.swiftmq.amqp.v100.generated.messaging.delivery_state.Accepted)

Example 3 with DeliveryNumber

use of com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber in project swiftmq-ce by iitsoftware.

the class SessionHandler method doSendOneMessage.

private void doSendOneMessage(SourceMessageProcessor sourceMessageProcessor, SourceLink sourceLink, Delivery delivery, boolean restart) throws EndWithErrorException {
    try {
        if (remoteIncomingWindow > 0 && outgoingWindow > 0) {
            do {
                boolean wasFirstPacket = false;
                delivery.setMaxFrameSize(amqpHandler.getMaxFrameSize());
                TransferFrame frame = new TransferFrame(channel);
                frame.setHandle(new Handle(sourceLink.getHandle()));
                frame.setSettled(new AMQPBoolean(sourceLink.getSndSettleMode() == SenderSettleMode.SETTLED.getValue()));
                if (delivery.getCurrentPacketNumber() == 0) {
                    if (ctx.traceSpace.enabled)
                        ctx.traceSpace.trace(ctx.amqpSwiftlet.getName(), toString() + ", doSendOneMessage, amqpMessage=" + delivery.getAmqpMessage());
                    long totalSize = delivery.getSize();
                    wasFirstPacket = true;
                    sourceLink.incDeliveryCountSnd();
                    long dId = nextDeliveryId();
                    frame.setDeliveryId(new DeliveryNumber(dId));
                    frame.setDeliveryTag(createDeliveryTag(delivery));
                    TxnIdIF currentTx = sourceLink.getCurrentTx();
                    if (currentTx != null) {
                        TransactionalState tState = new TransactionalState();
                        tState.setTxnId(currentTx);
                        frame.setState(tState);
                        transactionRegistry.addToTransaction(currentTx, sourceLink, dId, delivery.getMessageIndex(), totalSize);
                        totalSize = 0;
                    }
                    if (!frame.getSettled().getValue()) {
                        unsettledOutgoingDeliveries.put(dId, sourceLink);
                        if (totalSize > 0)
                            sourceLink.addUnsettled(dId, delivery.getMessageIndex(), totalSize);
                        else
                            sourceLink.addUnsettled(dId, delivery.getMessageIndex());
                    } else {
                        sourceLink.autoack(delivery.getMessageIndex());
                    }
                    incMsgsSent(1);
                }
                delivery.getNextPacket(frame);
                // We may increase the outgoing window and send a flow before
                if (wasFirstPacket && outgoingWindow - delivery.getPredictedNumberPackets() < 0) {
                    outgoingWindow += delivery.getPredictedNumberPackets();
                    sendFlow();
                    windowChanged = true;
                }
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.amqpSwiftlet.getName(), toString() + ", doSendOneMessage, remoteIncomingWindows=" + remoteIncomingWindow + ", outgoingWindow=" + outgoingWindow + ", sending message, wasFirstPacket=" + wasFirstPacket + ", maxSize=" + delivery.getMaxPayloadLength() + ", packetSize=" + frame.getPayload().length + ", predictedNumberPackets=" + delivery.getPredictedNumberPackets() + ", currentPacket=" + delivery.getCurrentPacketNumber() + ", hasMore=" + delivery.hasMore());
                versionedConnection.send(frame);
                if (!frame.getSettled().getValue())
                    outgoingWindow--;
                nextOutgoingId++;
                remoteIncomingWindow--;
                if (!delivery.hasMore()) {
                    if (restart) {
                        if (sourceLink.getLinkCredit() > 0)
                            sourceLink.startMessageProcessor(sourceMessageProcessor);
                        else
                            sourceLink.clearMessageProcessor();
                    }
                    // 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 = initialOutgoingWindow;
                        sendFlow();
                    }
                    break;
                }
            } while (remoteIncomingWindow > 0 && outgoingWindow > 0);
            if (delivery.hasMore()) {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.amqpSwiftlet.getName(), toString() + ", doSendOneMessage, remoteIncomingWindows=" + remoteIncomingWindow + ", outgoingWindow=" + outgoingWindow + ", has more but no window, storing message");
                outboundDeliveries.add(new OutboundDelivery(sourceMessageProcessor, sourceLink, delivery, restart));
            }
        } else {
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.amqpSwiftlet.getName(), toString() + ", doSendOneMessage, no remote incoming window = " + remoteIncomingWindow + ", outgoingWindow=" + outgoingWindow + ", store for later transfer");
            outboundDeliveries.add(new OutboundDelivery(sourceMessageProcessor, sourceLink, delivery, restart));
        }
    } catch (IOException e) {
        throw new ConnectionEndException(AmqpError.INTERNAL_ERROR, new AMQPString("IOException during outbound send: " + e.getMessage()));
    } catch (QueueException e) {
        throw new ConnectionEndException(AmqpError.INTERNAL_ERROR, new AMQPString("QueueException during outbound send: " + e.getMessage()));
    }
}
Also used : TxnIdIF(com.swiftmq.amqp.v100.generated.transactions.coordination.TxnIdIF) IOException(java.io.IOException) TransactionalState(com.swiftmq.amqp.v100.generated.transactions.coordination.TransactionalState) QueueException(com.swiftmq.swiftlet.queue.QueueException)

Example 4 with DeliveryNumber

use of com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber in project swiftmq-client by iitsoftware.

the class DispositionFrame method decode.

private void decode() throws Exception {
    List l = body.getValue();
    AMQPType t = null;
    int idx = 0;
    // Factory  : ./.
    if (idx >= l.size())
        return;
    t = (AMQPType) l.get(idx++);
    if (t.getCode() == AMQPTypeDecoder.NULL)
        throw new Exception("Mandatory field 'role' in 'Disposition' frame is NULL");
    try {
        role = new Role(((AMQPBoolean) t).getValue());
    } catch (ClassCastException e) {
        throw new Exception("Invalid type of field 'role' in 'Disposition' frame: " + e);
    }
    // Factory  : ./.
    if (idx >= l.size())
        return;
    t = (AMQPType) l.get(idx++);
    if (t.getCode() == AMQPTypeDecoder.NULL)
        throw new Exception("Mandatory field 'first' in 'Disposition' frame is NULL");
    try {
        first = new DeliveryNumber(((AMQPUnsignedInt) t).getValue());
    } catch (ClassCastException e) {
        throw new Exception("Invalid type of field 'first' in 'Disposition' frame: " + e);
    }
    // Factory  : ./.
    if (idx >= l.size())
        return;
    t = (AMQPType) l.get(idx++);
    try {
        if (t.getCode() != AMQPTypeDecoder.NULL)
            last = new DeliveryNumber(((AMQPUnsignedInt) t).getValue());
    } catch (ClassCastException e) {
        throw new Exception("Invalid type of field 'last' in 'Disposition' frame: " + e);
    }
    // Factory  : ./.
    if (idx >= l.size())
        return;
    t = (AMQPType) l.get(idx++);
    try {
        if (t.getCode() != AMQPTypeDecoder.NULL)
            settled = (AMQPBoolean) t;
    } catch (ClassCastException e) {
        throw new Exception("Invalid type of field 'settled' in 'Disposition' frame: " + e);
    }
    // Factory  : DeliveryStateFactory
    if (idx >= l.size())
        return;
    t = (AMQPType) l.get(idx++);
    if (t.getCode() != AMQPTypeDecoder.NULL)
        state = DeliveryStateFactory.create(t);
    // Factory  : ./.
    if (idx >= l.size())
        return;
    t = (AMQPType) l.get(idx++);
    try {
        if (t.getCode() != AMQPTypeDecoder.NULL)
            batchable = (AMQPBoolean) t;
    } catch (ClassCastException e) {
        throw new Exception("Invalid type of field 'batchable' in 'Disposition' frame: " + e);
    }
}
Also used : Role(com.swiftmq.amqp.v100.generated.transport.definitions.Role) DeliveryNumber(com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber) List(java.util.List) ArrayList(java.util.ArrayList) IOException(java.io.IOException)

Example 5 with DeliveryNumber

use of com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber in project swiftmq-client by iitsoftware.

the class SessionDispatcher method visit.

public void visit(POSendResumedTransfer po) {
    if (pTracer.isEnabled())
        pTracer.trace(toString(), ", visit, po=" + po + " ...");
    TransferFrame frame = new TransferFrame(mySession.getChannel());
    frame.setHandle(new Handle(po.getProducer().getHandle()));
    frame.setSettled(new AMQPBoolean(true));
    frame.setResume(new AMQPBoolean(true));
    frame.setDeliveryId(new DeliveryNumber(nextOutgoingId++));
    frame.setDeliveryTag(po.getDeliveryTag());
    frame.setState(new Accepted());
    outboundHandler.send(frame);
    if (pTracer.isEnabled())
        pTracer.trace(toString(), ", visit, po=" + po + " done");
}
Also used : Accepted(com.swiftmq.amqp.v100.generated.messaging.delivery_state.Accepted)

Aggregations

IOException (java.io.IOException)3 Accepted (com.swiftmq.amqp.v100.generated.messaging.delivery_state.Accepted)2 TransactionalState (com.swiftmq.amqp.v100.generated.transactions.coordination.TransactionalState)2 TxnIdIF (com.swiftmq.amqp.v100.generated.transactions.coordination.TxnIdIF)2 DeliveryNumber (com.swiftmq.amqp.v100.generated.transport.definitions.DeliveryNumber)1 Role (com.swiftmq.amqp.v100.generated.transport.definitions.Role)1 Packager (com.swiftmq.amqp.v100.transport.Packager)1 QueueException (com.swiftmq.swiftlet.queue.QueueException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1