TopicMessageImpl(String topicPartitionName, String topicName, Message<T> msg) { this.topicPartitionName = topicPartitionName; this.msg = msg; this.messageId = new TopicMessageIdImpl(topicPartitionName, topicName, msg.getMessageId()); }
private void removeExpiredMessagesFromQueue(Set<MessageId> messageIds) { Message<T> peek = incomingMessages.peek(); if (peek != null) { if (!messageIds.contains(peek.getMessageId())) { // first message is not expired, then no message is expired in queue. return; } // try not to remove elements that are added while we remove Message<T> message = incomingMessages.poll(); checkState(message instanceof TopicMessageImpl); while (message != null) { MessageId messageId = message.getMessageId(); if (!messageIds.contains(messageId)) { messageIds.add(messageId); break; } message = incomingMessages.poll(); } } }
@Override public void acknowledge(Message<?> message) throws PulsarClientException { try { acknowledge(message.getMessageId()); } catch (NullPointerException npe) { throw new PulsarClientException.InvalidMessageException(npe.getMessage()); } }
@Override public void acknowledgeCumulative(Message<?> message) throws PulsarClientException { try { acknowledgeCumulative(message.getMessageId()); } catch (NullPointerException npe) { throw new PulsarClientException.InvalidMessageException(npe.getMessage()); } }
@Override protected Message<T> internalReceive() throws PulsarClientException { Message<T> message; try { message = incomingMessages.take(); checkState(message instanceof TopicMessageImpl); unAckedMessageTracker.add(message.getMessageId()); resumeReceivingFromPausedConsumersIfNeeded(); return message; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new PulsarClientException(e); } }
@Override protected Message<T> internalReceive(int timeout, TimeUnit unit) throws PulsarClientException { Message<T> message; try { message = incomingMessages.poll(timeout, unit); if (message != null) { checkArgument(message instanceof TopicMessageImpl); unAckedMessageTracker.add(message.getMessageId()); } resumeReceivingFromPausedConsumersIfNeeded(); return message; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new PulsarClientException(e); } }
private void triggerZeroQueueSizeListener(final Message<T> message) { checkArgument(conf.getReceiverQueueSize() == 0); checkNotNull(listener, "listener can't be null"); checkNotNull(message, "unqueued message can't be null"); listenerExecutor.execute(() -> { stats.updateNumMsgsReceived(message); try { if (log.isDebugEnabled()) { log.debug("[{}][{}] Calling message listener for unqueued message {}", topic, subscription, message.getMessageId()); } listener.received(ConsumerImpl.this, message); } catch (Throwable t) { log.error("[{}][{}] Message listener error in processing unqueued message: {}", topic, subscription, message.getMessageId(), t); } increaseAvailablePermits(cnx()); }); }
@Override protected CompletableFuture<Message<T>> internalReceiveAsync() { CompletableFuture<Message<T>> result = new CompletableFuture<>(); Message<T> message; try { lock.writeLock().lock(); message = incomingMessages.poll(0, TimeUnit.SECONDS); if (message == null) { pendingReceives.add(result); } else { checkState(message instanceof TopicMessageImpl); unAckedMessageTracker.add(message.getMessageId()); resumeReceivingFromPausedConsumersIfNeeded(); result.complete(message); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); result.completeExceptionally(new PulsarClientException(e)); } finally { lock.writeLock().unlock(); } return result; }
@Override public CompletableFuture<Void> acknowledgeCumulativeAsync(Message<?> message) { try { return acknowledgeCumulativeAsync(message.getMessageId()); } catch (NullPointerException npe) { return FutureUtil.failedFuture(new PulsarClientException.InvalidMessageException(npe.getMessage())); } }
/** * This is called when client sends message to pulsar broker, before key and value gets serialized. * The method calls {@link ProducerInterceptor#beforeSend(Producer,Message)} method. Message returned from * first interceptor's beforeSend() is passed to the second interceptor beforeSend(), and so on in the * interceptor chain. The message returned from the last interceptor is returned from this method. * * This method does not throw exceptions. Exceptions thrown by any interceptor methods are caught and ignored. * If a interceptor in the middle of the chain, that normally modifies the message, throws an exception, * the next interceptor in the chain will be called with a message returned by the previous interceptor that did * not throw an exception. * * @param producer the producer which contains the interceptor. * @param message the message from client * @return the message to send to topic/partition */ public Message<T> beforeSend(Producer<T> producer, Message<T> message) { Message<T> interceptorMessage = message; for (int i = 0; i < interceptors.size(); i++) { try { interceptorMessage = interceptors.get(i).beforeSend(producer, interceptorMessage); } catch (Exception e) { if (message != null && producer != null) { log.warn("Error executing interceptor beforeSend callback for messageId: {}, topicName:{} ", message.getMessageId(), producer.getTopic(), e); } else { log.warn("Error Error executing interceptor beforeSend callback ", e); } } } return interceptorMessage; }
@Override public CompletableFuture<Void> acknowledgeAsync(Message<?> message) { try { return acknowledgeAsync(message.getMessageId()); } catch (NullPointerException npe) { return FutureUtil.failedFuture(new PulsarClientException.InvalidMessageException(npe.getMessage())); } }
topic, subscription, message.getMessageId()); if (log.isDebugEnabled()) { log.debug("[{}][{}] Calling message listener for message {}", topic, subscription, message.getMessageId());
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; }
lastDequeuedMessage = message.getMessageId(); ClientCnx msgCnx = ((MessageImpl<?>) message).getCnx();
/** * 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 BatchMessageIdImpl clearReceiverQueue() { List<Message<?>> currentMessageQueue = new ArrayList<>(incomingMessages.size()); incomingMessages.drainTo(currentMessageQueue); if (!currentMessageQueue.isEmpty()) { MessageIdImpl nextMessageInQueue = (MessageIdImpl) currentMessageQueue.get(0).getMessageId(); BatchMessageIdImpl previousMessage; if (nextMessageInQueue instanceof BatchMessageIdImpl) { // Get on the previous message within the current batch previousMessage = new BatchMessageIdImpl(nextMessageInQueue.getLedgerId(), nextMessageInQueue.getEntryId(), nextMessageInQueue.getPartitionIndex(), ((BatchMessageIdImpl) nextMessageInQueue).getBatchIndex() - 1); } else { // Get on previous message in previous entry previousMessage = new BatchMessageIdImpl(nextMessageInQueue.getLedgerId(), nextMessageInQueue.getEntryId() - 1, nextMessageInQueue.getPartitionIndex(), -1); } return previousMessage; } else if (!lastDequeuedMessage.equals(MessageId.earliest)) { // 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 new BatchMessageIdImpl((MessageIdImpl) lastDequeuedMessage); } else { // No message was received or dequeued by this consumer. Next message would still be the startMessageId return startMessageId; } }
protected void trackMessage(Message<?> msg) { if (msg != null) { MessageId messageId = msg.getMessageId(); if (conf.getAckTimeoutMillis() > 0 && messageId instanceof MessageIdImpl) { MessageIdImpl id = (MessageIdImpl)messageId; if (id instanceof BatchMessageIdImpl) { // do not add each item in batch message into tracker id = new MessageIdImpl(id.getLedgerId(), id.getEntryId(), getPartitionIndex()); } unAckedMessageTracker.add(id); } } }
if (log.isDebugEnabled()) { log.debug("[{}][{}] Calling message listener for message {}", topic, subscription, msg.getMessageId()); msg.getMessageId(), t);
/** * 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 = 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()); } if (partitionIndex != -1) { // we should no longer track this message, TopicsConsumer will take care from now onwards unAckedMessageTracker.remove(id); } else { unAckedMessageTracker.add(id); } } }
@Override public void acknowledgeCumulative(Message<?> message) throws PulsarClientException { try { acknowledgeCumulative(message.getMessageId()); } catch (NullPointerException npe) { throw new PulsarClientException.InvalidMessageException(npe.getMessage()); } }
@Override public CompletableFuture<Void> acknowledgeCumulativeAsync(Message<?> message) { try { return acknowledgeCumulativeAsync(message.getMessageId()); } catch (NullPointerException npe) { return FutureUtil.failedFuture(new PulsarClientException.InvalidMessageException(npe.getMessage())); } }