Search in sources :

Example 11 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class ConsumerImpl method connectionOpened.

@Override
public void connectionOpened(final ClientCnx cnx) {
    setClientCnx(cnx);
    cnx.registerConsumer(consumerId, this);
    log.info("[{}][{}] Subscribing to topic on cnx {}", topic, subscription, cnx.ctx().channel());
    long requestId = client.newRequestId();
    int currentSize;
    synchronized (this) {
        currentSize = incomingMessages.size();
        startMessageId = clearReceiverQueue();
        unAckedMessageTracker.clear();
    }
    boolean isDurable = subscriptionMode == SubscriptionMode.Durable;
    MessageIdData startMessageIdData;
    if (isDurable) {
        // For regular durable subscriptions, the message id from where to restart will be determined by the broker.
        startMessageIdData = null;
    } else {
        // For non-durable we are going to restart from the next entry
        MessageIdData.Builder builder = MessageIdData.newBuilder();
        builder.setLedgerId(startMessageId.getLedgerId());
        builder.setEntryId(startMessageId.getEntryId());
        if (startMessageId instanceof BatchMessageIdImpl) {
            builder.setBatchIndex(((BatchMessageIdImpl) startMessageId).getBatchIndex());
        }
        startMessageIdData = builder.build();
        builder.recycle();
    }
    ByteBuf request = Commands.newSubscribe(topic, subscription, consumerId, requestId, getSubType(), priorityLevel, consumerName, isDurable, startMessageIdData, metadata, readCompacted, InitialPosition.valueOf(subscriptionInitialPosition.getValue()));
    if (startMessageIdData != null) {
        startMessageIdData.recycle();
    }
    cnx.sendRequestWithId(request, requestId).thenRun(() -> {
        synchronized (ConsumerImpl.this) {
            if (changeToReadyState()) {
                log.info("[{}][{}] Subscribed to topic on {} -- consumer: {}", topic, subscription, cnx.channel().remoteAddress(), consumerId);
                AVAILABLE_PERMITS_UPDATER.set(this, 0);
                // or queue was not empty: send a flow command
                if (waitingOnReceiveForZeroQueueSize || (conf.getReceiverQueueSize() == 0 && currentSize > 0)) {
                    sendFlowPermitsToBroker(cnx, 1);
                }
            } else {
                // Consumer was closed while reconnecting, close the connection to make sure the broker
                // drops the consumer on its side
                setState(State.Closed);
                cnx.removeConsumer(consumerId);
                cnx.channel().close();
                return;
            }
        }
        resetBackoff();
        boolean firstTimeConnect = subscribeFuture.complete(this);
        // command to receive messages
        if (!(firstTimeConnect && partitionIndex > -1) && conf.getReceiverQueueSize() != 0) {
            sendFlowPermitsToBroker(cnx, conf.getReceiverQueueSize());
        }
    }).exceptionally((e) -> {
        cnx.removeConsumer(consumerId);
        if (getState() == State.Closing || getState() == State.Closed) {
            // Consumer was closed while reconnecting, close the connection to make sure the broker
            // drops the consumer on its side
            cnx.channel().close();
            return null;
        }
        log.warn("[{}][{}] Failed to subscribe to topic on {}", topic, subscription, cnx.channel().remoteAddress());
        if (e.getCause() instanceof PulsarClientException && getConnectionHandler().isRetriableError((PulsarClientException) e.getCause()) && System.currentTimeMillis() < subscribeTimeout) {
            reconnectLater(e.getCause());
            return null;
        }
        if (!subscribeFuture.isDone()) {
            // unable to create new consumer, fail operation
            setState(State.Failed);
            subscribeFuture.completeExceptionally(e);
            client.cleanupConsumer(this);
        } else {
            // consumer was subscribed and connected but we got some error, keep trying
            reconnectLater(e.getCause());
        }
        return null;
    });
}
Also used : MessageIdData(org.apache.pulsar.common.api.proto.PulsarApi.MessageIdData) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ByteBuf(io.netty.buffer.ByteBuf)

Example 12 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class PartitionedConsumerImpl method internalReceive.

@Override
protected Message<T> internalReceive() throws PulsarClientException {
    Message<T> message;
    try {
        message = incomingMessages.take();
        unAckedMessageTracker.add((MessageIdImpl) message.getMessageId());
        resumeReceivingFromPausedConsumersIfNeeded();
        return message;
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new PulsarClientException(e);
    }
}
Also used : PulsarClientException(org.apache.pulsar.client.api.PulsarClientException)

Example 13 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class PartitionedConsumerImpl method internalReceive.

@Override
protected Message<T> internalReceive(int timeout, TimeUnit unit) throws PulsarClientException {
    Message<T> message;
    try {
        message = incomingMessages.poll(timeout, unit);
        if (message != null) {
            unAckedMessageTracker.add(message.getMessageId());
        }
        resumeReceivingFromPausedConsumersIfNeeded();
        return message;
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new PulsarClientException(e);
    }
}
Also used : PulsarClientException(org.apache.pulsar.client.api.PulsarClientException)

Example 14 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class ProducerImpl method sendAsync.

public void sendAsync(Message<T> message, SendCallback callback) {
    checkArgument(message instanceof MessageImpl);
    if (!isValidProducerState(callback)) {
        return;
    }
    if (!canEnqueueRequest(callback)) {
        return;
    }
    MessageImpl<T> msg = (MessageImpl<T>) message;
    MessageMetadata.Builder msgMetadata = msg.getMessageBuilder();
    ByteBuf payload = msg.getDataBuffer();
    // If compression is enabled, we are compressing, otherwise it will simply use the same buffer
    int uncompressedSize = payload.readableBytes();
    ByteBuf compressedPayload = payload;
    // batch will be compressed when closed
    if (!isBatchMessagingEnabled()) {
        compressedPayload = compressor.encode(payload);
        payload.release();
    }
    int compressedSize = compressedPayload.readableBytes();
    // batch)
    if (compressedSize > PulsarDecoder.MaxMessageSize) {
        compressedPayload.release();
        String compressedStr = (!isBatchMessagingEnabled() && conf.getCompressionType() != CompressionType.NONE) ? "Compressed" : "";
        callback.sendComplete(new PulsarClientException.InvalidMessageException(format("%s Message payload size %d cannot exceed %d bytes", compressedStr, compressedSize, PulsarDecoder.MaxMessageSize)));
        return;
    }
    if (!msg.isReplicated() && msgMetadata.hasProducerName()) {
        callback.sendComplete(new PulsarClientException.InvalidMessageException("Cannot re-use the same message"));
        compressedPayload.release();
        return;
    }
    try {
        synchronized (this) {
            long sequenceId;
            if (!msgMetadata.hasSequenceId()) {
                sequenceId = msgIdGeneratorUpdater.getAndIncrement(this);
                msgMetadata.setSequenceId(sequenceId);
            } else {
                sequenceId = msgMetadata.getSequenceId();
            }
            if (!msgMetadata.hasPublishTime()) {
                msgMetadata.setPublishTime(System.currentTimeMillis());
                checkArgument(!msgMetadata.hasProducerName());
                msgMetadata.setProducerName(producerName);
                if (conf.getCompressionType() != CompressionType.NONE) {
                    msgMetadata.setCompression(convertCompressionType(conf.getCompressionType()));
                    msgMetadata.setUncompressedSize(uncompressedSize);
                }
            }
            if (isBatchMessagingEnabled()) {
                // batch size and/or max message size
                if (batchMessageContainer.hasSpaceInBatch(msg)) {
                    batchMessageContainer.add(msg, callback);
                    payload.release();
                    if (batchMessageContainer.numMessagesInBatch == maxNumMessagesInBatch || batchMessageContainer.currentBatchSizeBytes >= BatchMessageContainer.MAX_MESSAGE_BATCH_SIZE_BYTES) {
                        batchMessageAndSend();
                    }
                } else {
                    doBatchSendAndAdd(msg, callback, payload);
                }
            } else {
                ByteBuf encryptedPayload = encryptMessage(msgMetadata, compressedPayload);
                ByteBufPair cmd = sendMessage(producerId, sequenceId, 1, msgMetadata.build(), encryptedPayload);
                msgMetadata.recycle();
                final OpSendMsg op = OpSendMsg.create(msg, cmd, sequenceId, callback);
                op.setNumMessagesInBatch(1);
                op.setBatchSizeByte(encryptedPayload.readableBytes());
                pendingMessages.put(op);
                // Read the connection before validating if it's still connected, so that we avoid reading a null
                // value
                ClientCnx cnx = cnx();
                if (isConnected()) {
                    // If we do have a connection, the message is sent immediately, otherwise we'll try again once a
                    // new
                    // connection is established
                    cmd.retain();
                    cnx.ctx().channel().eventLoop().execute(WriteInEventLoopCallback.create(this, cnx, op));
                    stats.updateNumMsgsSent(op.numMessagesInBatch, op.batchSizeByte);
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug("[{}] [{}] Connection is not ready -- sequenceId {}", topic, producerName, sequenceId);
                    }
                }
            }
        }
    } catch (InterruptedException ie) {
        Thread.currentThread().interrupt();
        semaphore.release();
        callback.sendComplete(new PulsarClientException(ie));
    } catch (PulsarClientException e) {
        semaphore.release();
        callback.sendComplete(e);
    } catch (Throwable t) {
        semaphore.release();
        callback.sendComplete(new PulsarClientException(t));
    }
}
Also used : ByteBuf(io.netty.buffer.ByteBuf) ByteBufPair(org.apache.pulsar.common.api.ByteBufPair) MessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException)

Example 15 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class ProducerImpl method closeAsync.

@Override
public CompletableFuture<Void> closeAsync() {
    final State currentState = getAndUpdateState(state -> {
        if (state == State.Closed) {
            return state;
        }
        return State.Closing;
    });
    if (currentState == State.Closed || currentState == State.Closing) {
        return CompletableFuture.completedFuture(null);
    }
    Timeout timeout = sendTimeout;
    if (timeout != null) {
        timeout.cancel();
        sendTimeout = null;
    }
    Timeout batchTimeout = batchMessageAndSendTimeout;
    if (batchTimeout != null) {
        batchTimeout.cancel();
        batchMessageAndSendTimeout = null;
    }
    if (keyGeneratorTask != null && !keyGeneratorTask.isCancelled()) {
        keyGeneratorTask.cancel(false);
    }
    stats.cancelStatsTimeout();
    ClientCnx cnx = cnx();
    if (cnx == null || currentState != State.Ready) {
        log.info("[{}] [{}] Closed Producer (not connected)", topic, producerName);
        synchronized (this) {
            setState(State.Closed);
            client.cleanupProducer(this);
            PulsarClientException ex = new PulsarClientException.AlreadyClosedException("Producer was already closed");
            pendingMessages.forEach(msg -> {
                msg.callback.sendComplete(ex);
                msg.cmd.release();
                msg.recycle();
            });
            pendingMessages.clear();
        }
        return CompletableFuture.completedFuture(null);
    }
    long requestId = client.newRequestId();
    ByteBuf cmd = Commands.newCloseProducer(producerId, requestId);
    CompletableFuture<Void> closeFuture = new CompletableFuture<>();
    cnx.sendRequestWithId(cmd, requestId).handle((v, exception) -> {
        cnx.removeProducer(producerId);
        if (exception == null || !cnx.ctx().channel().isActive()) {
            // connection did break in the meantime. In any case, the producer is gone.
            synchronized (ProducerImpl.this) {
                log.info("[{}] [{}] Closed Producer", topic, producerName);
                setState(State.Closed);
                pendingMessages.forEach(msg -> {
                    msg.cmd.release();
                    msg.recycle();
                });
                pendingMessages.clear();
            }
            closeFuture.complete(null);
            client.cleanupProducer(this);
        } else {
            closeFuture.completeExceptionally(exception);
        }
        return null;
    });
    return closeFuture;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) Timeout(io.netty.util.Timeout) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ByteBuf(io.netty.buffer.ByteBuf)

Aggregations

PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)65 Test (org.testng.annotations.Test)24 CompletableFuture (java.util.concurrent.CompletableFuture)17 Message (org.apache.pulsar.client.api.Message)15 IOException (java.io.IOException)14 PulsarClient (org.apache.pulsar.client.api.PulsarClient)13 ExecutionException (java.util.concurrent.ExecutionException)12 Consumer (org.apache.pulsar.client.api.Consumer)12 MessageId (org.apache.pulsar.client.api.MessageId)12 Producer (org.apache.pulsar.client.api.Producer)12 ByteBuf (io.netty.buffer.ByteBuf)11 List (java.util.List)8 ConsumerConfiguration (org.apache.pulsar.client.api.ConsumerConfiguration)8 ProducerConfiguration (org.apache.pulsar.client.api.ProducerConfiguration)7 ArrayList (java.util.ArrayList)6 HashSet (java.util.HashSet)6 Map (java.util.Map)6 Logger (org.slf4j.Logger)6 LoggerFactory (org.slf4j.LoggerFactory)6 TimeUnit (java.util.concurrent.TimeUnit)5