/** * Clear the internal receiver queue and returns the message id of what was the 1st message in the queue that was * not seen by the application */ private MessageIdImpl clearReceiverQueue() { List<Message> currentMessageQueue = new ArrayList<>(incomingMessages.size()); incomingMessages.drainTo(currentMessageQueue); if (!currentMessageQueue.isEmpty()) { MessageIdImpl nextMessageInQueue = (MessageIdImpl) currentMessageQueue.get(0).getMessageId(); MessageIdImpl previousMessage = new MessageIdImpl(nextMessageInQueue.getLedgerId(), nextMessageInQueue.getEntryId() - 1, nextMessageInQueue.getPartitionIndex()); return previousMessage; } else if (lastDequeuedMessage != null) { // If the queue was empty we need to restart from the message just after the last one that has been dequeued // in the past return lastDequeuedMessage; } else { // No message was received or dequeued by this consumer. Next message would still be the startMessageId return (MessageIdImpl) startMessageId; } }
public int removeMessagesTill(MessageIdImpl msgId) { readLock.lock(); try { int currentSetRemovedMsgCount = currentSet.removeIf(m -> ((m.getLedgerId() < msgId.getLedgerId() || (m.getLedgerId() == msgId.getLedgerId() && m.getEntryId() <= msgId.getEntryId())) && m.getPartitionIndex() == msgId.getPartitionIndex())); int oldSetRemovedMsgCount = oldOpenSet.removeIf(m -> ((m.getLedgerId() < msgId.getLedgerId() || (m.getLedgerId() == msgId.getLedgerId() && m.getEntryId() <= msgId.getEntryId())) && m.getPartitionIndex() == msgId.getPartitionIndex())); return currentSetRemovedMsgCount + oldSetRemovedMsgCount; } finally { readLock.unlock(); } }
private CompletableFuture<? extends Subscription> getNonDurableSubscription(String subscriptionName, MessageId startMessageId) { CompletableFuture<Subscription> subscriptionFuture = new CompletableFuture<>(); Subscription subscription = subscriptions.computeIfAbsent(subscriptionName, name -> { // Create a new non-durable cursor only for the first consumer that connects MessageIdImpl msgId = startMessageId != null ? (MessageIdImpl) startMessageId : (MessageIdImpl) MessageId.latest; Position startPosition = new PositionImpl(msgId.getLedgerId(), msgId.getEntryId()); ManagedCursor cursor = null; try { cursor = ledger.newNonDurableCursor(startPosition); } catch (ManagedLedgerException e) { subscriptionFuture.completeExceptionally(e); } return new PersistentSubscription(this, subscriptionName, cursor); }); if (!subscriptionFuture.isDone()) { subscriptionFuture.complete(subscription); } else { // failed to initialize managed-cursor: clean up created subscription subscriptions.remove(subscriptionName); } return subscriptionFuture; }
private MessageIdImpl getMessageIdImpl(Message msg) { MessageIdImpl messageId = (MessageIdImpl) msg.getMessageId(); if (messageId instanceof BatchMessageIdImpl) { // messageIds contain MessageIdImpl, not BatchMessageIdImpl messageId = new MessageIdImpl(messageId.getLedgerId(), messageId.getEntryId(), getPartitionIndex()); } return messageId; }
private CompletableFuture<Void> sendAcknowledge(MessageId messageId, AckType ackType) { MessageIdImpl msgId = (MessageIdImpl) messageId; final ByteBuf cmd = Commands.newAck(consumerId, msgId.getLedgerId(), msgId.getEntryId(), ackType, null);
builder.setPartition(messageId.getPartitionIndex()); builder.setLedgerId(messageId.getLedgerId()); builder.setEntryId(messageId.getEntryId()); return builder.build(); }).collect(Collectors.toList());
builder.setEntryId(startMessageId.getEntryId()); startMessageIdData = builder.build(); builder.recycle();
/** * Record the event that one message has been processed by the application. * * Periodically, it sends a Flow command to notify the broker that it can push more messages */ protected synchronized void messageProcessed(Message msg) { ClientCnx currentCnx = cnx(); ClientCnx msgCnx = ((MessageImpl) msg).getCnx(); lastDequeuedMessage = (MessageIdImpl) msg.getMessageId(); if (msgCnx != currentCnx) { // The processed message did belong to the old queue that was cleared after reconnection. return; } increaseAvailablePermits(currentCnx); stats.updateNumMsgsReceived(msg); if (conf.getAckTimeoutMillis() != 0) { // reset timer for messages that are received by the client MessageIdImpl id = (MessageIdImpl) msg.getMessageId(); if (id instanceof BatchMessageIdImpl) { id = new MessageIdImpl(id.getLedgerId(), id.getEntryId(), getPartitionIndex()); } unAckedMessageTracker.add(id); } }