Search in sources :

Example 1 with MessageIdData

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData in project pulsar by yahoo.

the class ConsumerImpl method redeliverUnacknowledgedMessages.

@Override
public void redeliverUnacknowledgedMessages(Set<MessageIdImpl> messageIds) {
    if (conf.getSubscriptionType() != SubscriptionType.Shared) {
        // We cannot redeliver single messages if subscription type is not Shared
        redeliverUnacknowledgedMessages();
        return;
    }
    ClientCnx cnx = cnx();
    if (isConnected() && cnx.getRemoteEndpointProtocolVersion() >= ProtocolVersion.v2.getNumber()) {
        int messagesFromQueue = removeExpiredMessagesFromQueue(messageIds);
        Iterable<List<MessageIdImpl>> batches = Iterables.partition(messageIds, MAX_REDELIVER_UNACKNOWLEDGED);
        MessageIdData.Builder builder = MessageIdData.newBuilder();
        batches.forEach(ids -> {
            List<MessageIdData> messageIdDatas = ids.stream().map(messageId -> {
                batchMessageAckTracker.remove(messageId);
                builder.setPartition(messageId.getPartitionIndex());
                builder.setLedgerId(messageId.getLedgerId());
                builder.setEntryId(messageId.getEntryId());
                return builder.build();
            }).collect(Collectors.toList());
            ByteBuf cmd = Commands.newRedeliverUnacknowledgedMessages(consumerId, messageIdDatas);
            cnx.ctx().writeAndFlush(cmd, cnx.ctx().voidPromise());
            messageIdDatas.forEach(MessageIdData::recycle);
        });
        if (messagesFromQueue > 0) {
            increaseAvailablePermits(cnx, messagesFromQueue);
        }
        builder.recycle();
        if (log.isDebugEnabled()) {
            log.debug("[{}] [{}] [{}] Redeliver unacked messages and increase {} permits", subscription, topic, consumerName, messagesFromQueue);
        }
        return;
    }
    if (cnx == null || (getState() == State.Connecting)) {
        log.warn("[{}] Client Connection needs to be establised for redelivery of unacknowledged messages", this);
    } else {
        log.warn("[{}] Reconnecting the client to redeliver the messages.", this);
        cnx.ctx().close();
    }
}
Also used : AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) Iterables(com.google.common.collect.Iterables) Consumer(com.yahoo.pulsar.client.api.Consumer) MessageId(com.yahoo.pulsar.client.api.MessageId) CompressionCodec(com.yahoo.pulsar.common.compression.CompressionCodec) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) PulsarDecoder(com.yahoo.pulsar.common.api.PulsarDecoder) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) SubscriptionType(com.yahoo.pulsar.client.api.SubscriptionType) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ByteBuf(io.netty.buffer.ByteBuf) FutureUtil(com.yahoo.pulsar.client.util.FutureUtil) Commands(com.yahoo.pulsar.common.api.Commands) ExecutorService(java.util.concurrent.ExecutorService) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) Commands.hasChecksum(com.yahoo.pulsar.common.api.Commands.hasChecksum) CompressionType(com.yahoo.pulsar.common.api.proto.PulsarApi.CompressionType) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) Commands.readChecksum(com.yahoo.pulsar.common.api.Commands.readChecksum) Crc32cChecksum.computeChecksum(com.yahoo.pulsar.checksum.utils.Crc32cChecksum.computeChecksum) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) ConsumerConfiguration(com.yahoo.pulsar.client.api.ConsumerConfiguration) Set(java.util.Set) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) IOException(java.io.IOException) CompressionCodecProvider(com.yahoo.pulsar.common.compression.CompressionCodecProvider) NavigableMap(java.util.NavigableMap) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) TimeUnit(java.util.concurrent.TimeUnit) ProtocolVersion(com.yahoo.pulsar.common.api.proto.PulsarApi.ProtocolVersion) MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) List(java.util.List) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) PulsarApi(com.yahoo.pulsar.common.api.proto.PulsarApi) AckType(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandAck.AckType) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) MessageIdData(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData) Message(com.yahoo.pulsar.client.api.Message) BitSet(java.util.BitSet) Future(io.netty.util.concurrent.Future) ValidationError(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandAck.ValidationError) MessageIdData(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData) List(java.util.List) ByteBuf(io.netty.buffer.ByteBuf)

Example 2 with MessageIdData

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData in project pulsar by yahoo.

the class MessageIdImpl method toByteArray.

// batchIndex is -1 if message is non-batched message and has the batchIndex for a batch message
protected byte[] toByteArray(int batchIndex) {
    MessageIdData.Builder builder = MessageIdData.newBuilder();
    builder.setLedgerId(ledgerId);
    builder.setEntryId(entryId);
    if (partitionIndex >= 0) {
        builder.setPartition(partitionIndex);
    }
    if (batchIndex != -1) {
        builder.setBatchIndex(batchIndex);
    }
    MessageIdData msgId = builder.build();
    int size = msgId.getSerializedSize();
    ByteBuf serialized = Unpooled.buffer(size, size);
    ByteBufCodedOutputStream stream = ByteBufCodedOutputStream.get(serialized);
    try {
        msgId.writeTo(stream);
    } catch (IOException e) {
        // This is in-memory serialization, should not fail
        throw new RuntimeException(e);
    }
    msgId.recycle();
    builder.recycle();
    stream.recycle();
    return serialized.array();
}
Also used : MessageIdData(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData) IOException(java.io.IOException) ByteBuf(io.netty.buffer.ByteBuf) ByteBufCodedOutputStream(com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream)

Example 3 with MessageIdData

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData in project pulsar by yahoo.

the class Commands method newAck.

public static ByteBuf newAck(long consumerId, long ledgerId, long entryId, AckType ackType, ValidationError validationError) {
    CommandAck.Builder ackBuilder = CommandAck.newBuilder();
    ackBuilder.setConsumerId(consumerId);
    ackBuilder.setAckType(ackType);
    MessageIdData.Builder messageIdDataBuilder = MessageIdData.newBuilder();
    messageIdDataBuilder.setLedgerId(ledgerId);
    messageIdDataBuilder.setEntryId(entryId);
    MessageIdData messageIdData = messageIdDataBuilder.build();
    ackBuilder.setMessageId(messageIdData);
    if (validationError != null) {
        ackBuilder.setValidationError(validationError);
    }
    CommandAck ack = ackBuilder.build();
    ByteBuf res = serializeWithSize(BaseCommand.newBuilder().setType(Type.ACK).setAck(ack));
    ack.recycle();
    ackBuilder.recycle();
    messageIdDataBuilder.recycle();
    messageIdData.recycle();
    return res;
}
Also used : CommandAck(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandAck) MessageIdData(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData) UnpooledHeapByteBuf(io.netty.buffer.UnpooledHeapByteBuf) RecyclableDuplicateByteBuf(io.netty.buffer.RecyclableDuplicateByteBuf) ByteBuf(io.netty.buffer.ByteBuf)

Example 4 with MessageIdData

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData in project pulsar by yahoo.

the class Consumer method sendMessages.

/**
     * Dispatch a list of entries to the consumer.
     *
     * @return a promise that can be use to track when all the data has been written into the socket
     */
public Pair<ChannelPromise, Integer> sendMessages(final List<Entry> entries) {
    final ChannelHandlerContext ctx = cnx.ctx();
    final MutablePair<ChannelPromise, Integer> sentMessages = new MutablePair<ChannelPromise, Integer>();
    final ChannelPromise writePromise = ctx.newPromise();
    sentMessages.setLeft(writePromise);
    if (entries.isEmpty()) {
        if (log.isDebugEnabled()) {
            log.debug("[{}] List of messages is empty, triggering write future immediately for consumerId {}", subscription, consumerId);
        }
        writePromise.setSuccess();
        sentMessages.setRight(0);
        return sentMessages;
    }
    try {
        sentMessages.setRight(updatePermitsAndPendingAcks(entries));
    } catch (PulsarServerException pe) {
        log.warn("[{}] [{}] consumer doesn't support batch-message {}", subscription, consumerId, cnx.getRemoteEndpointProtocolVersion());
        subscription.markTopicWithBatchMessagePublished();
        sentMessages.setRight(0);
        // disconnect consumer: it will update dispatcher's availablePermits and resend pendingAck-messages of this
        // consumer to other consumer
        disconnect();
        return sentMessages;
    }
    ctx.channel().eventLoop().execute(() -> {
        for (int i = 0; i < entries.size(); i++) {
            Entry entry = entries.get(i);
            PositionImpl pos = (PositionImpl) entry.getPosition();
            MessageIdData.Builder messageIdBuilder = MessageIdData.newBuilder();
            MessageIdData messageId = messageIdBuilder.setLedgerId(pos.getLedgerId()).setEntryId(pos.getEntryId()).build();
            ByteBuf metadataAndPayload = entry.getDataBuffer();
            // skip checksum by incrementing reader-index if consumer-client doesn't support checksum verification
            if (cnx.getRemoteEndpointProtocolVersion() < ProtocolVersion.v6.getNumber()) {
                readChecksum(metadataAndPayload);
            }
            // stats
            msgOut.recordEvent(metadataAndPayload.readableBytes());
            if (log.isDebugEnabled()) {
                log.debug("[{}] Sending message to consumerId {}, entry id {}", subscription, consumerId, pos.getEntryId());
            }
            // We only want to pass the "real" promise on the last entry written
            ChannelPromise promise = ctx.voidPromise();
            if (i == (entries.size() - 1)) {
                promise = writePromise;
            }
            ctx.write(Commands.newMessage(consumerId, messageId, metadataAndPayload), promise);
            messageId.recycle();
            messageIdBuilder.recycle();
        }
        ctx.flush();
    });
    return sentMessages;
}
Also used : PulsarServerException(com.yahoo.pulsar.broker.PulsarServerException) MutablePair(org.apache.commons.lang3.tuple.MutablePair) Entry(org.apache.bookkeeper.mledger.Entry) MessageIdData(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelPromise(io.netty.channel.ChannelPromise) ByteBuf(io.netty.buffer.ByteBuf)

Example 5 with MessageIdData

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData in project pulsar by yahoo.

the class Consumer method redeliverUnacknowledgedMessages.

public void redeliverUnacknowledgedMessages(List<MessageIdData> messageIds) {
    int totalRedeliveryMessages = 0;
    List<PositionImpl> pendingPositions = Lists.newArrayList();
    for (MessageIdData msg : messageIds) {
        PositionImpl position = PositionImpl.get(msg.getLedgerId(), msg.getEntryId());
        Integer batchSize = pendingAcks.remove(position);
        if (batchSize != null) {
            totalRedeliveryMessages += batchSize;
            pendingPositions.add(position);
        }
    }
    UNACKED_MESSAGES_UPDATER.addAndGet(this, -totalRedeliveryMessages);
    blockedConsumerOnUnackedMsgs = false;
    subscription.redeliverUnacknowledgedMessages(this, pendingPositions);
    msgRedeliver.recordMultipleEvents(totalRedeliveryMessages, totalRedeliveryMessages);
    int numberOfBlockedPermits = Math.min(totalRedeliveryMessages, PERMITS_RECEIVED_WHILE_CONSUMER_BLOCKED_UPDATER.get(this));
    // if permitsReceivedWhileConsumerBlocked has been accumulated then pass it to Dispatcher to flow messages
    if (numberOfBlockedPermits > 0) {
        PERMITS_RECEIVED_WHILE_CONSUMER_BLOCKED_UPDATER.getAndAdd(this, -numberOfBlockedPermits);
        MESSAGE_PERMITS_UPDATER.getAndAdd(this, numberOfBlockedPermits);
        subscription.consumerFlow(this, numberOfBlockedPermits);
    }
}
Also used : MessageIdData(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl)

Aggregations

MessageIdData (com.yahoo.pulsar.common.api.proto.PulsarApi.MessageIdData)7 ByteBuf (io.netty.buffer.ByteBuf)5 PositionImpl (org.apache.bookkeeper.mledger.impl.PositionImpl)3 RecyclableDuplicateByteBuf (io.netty.buffer.RecyclableDuplicateByteBuf)2 UnpooledHeapByteBuf (io.netty.buffer.UnpooledHeapByteBuf)2 IOException (java.io.IOException)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Iterables (com.google.common.collect.Iterables)1 PulsarServerException (com.yahoo.pulsar.broker.PulsarServerException)1 Crc32cChecksum.computeChecksum (com.yahoo.pulsar.checksum.utils.Crc32cChecksum.computeChecksum)1 Consumer (com.yahoo.pulsar.client.api.Consumer)1 ConsumerConfiguration (com.yahoo.pulsar.client.api.ConsumerConfiguration)1 Message (com.yahoo.pulsar.client.api.Message)1 MessageId (com.yahoo.pulsar.client.api.MessageId)1 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)1 SubscriptionType (com.yahoo.pulsar.client.api.SubscriptionType)1 FutureUtil (com.yahoo.pulsar.client.util.FutureUtil)1 Commands (com.yahoo.pulsar.common.api.Commands)1 Commands.hasChecksum (com.yahoo.pulsar.common.api.Commands.hasChecksum)1