/** * Copyright 2016 Yahoo Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.yahoo.pulsar.client.api; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; import java.util.concurrent.TimeUnit; /** * Class specifying the configuration of a consumer. In Exclusive subscription, only a single consumer is allowed to * attach to the subscription. Other consumers will get an error message. In Shared subscription, multiple consumers * will be able to use the same subscription name and the messages will be dispatched in a round robin fashion. * * */ public class ConsumerConfiguration implements Serializable { /** * Resend shouldn't be requested before minAckTimeoutMillis. */ static long minAckTimeoutMillis = 1000; private static final long serialVersionUID = 1L; private SubscriptionType subscriptionType = SubscriptionType.Exclusive; private MessageListener messageListener; private int receiverQueueSize = 1000; private String consumerName = null; private long ackTimeoutMillis = 0; private int priorityLevel = 0; /** * @return the configured timeout in milliseconds for unacked messages. */ public long getAckTimeoutMillis() { return ackTimeoutMillis; } /** * Set the timeout for unacked messages, truncated to the nearest millisecond. The timeout needs to be greater than * 10 seconds. * * @param ackTimeout * for unacked messages. * @param timeUnit * unit in which the timeout is provided. * @return {@link ConsumerConfiguration} */ public ConsumerConfiguration setAckTimeout(long ackTimeout, TimeUnit timeUnit) { long ackTimeoutMillis = timeUnit.toMillis(ackTimeout); checkArgument(ackTimeoutMillis >= minAckTimeoutMillis, "Ack timeout should be should be greater than " + minAckTimeoutMillis + " ms"); this.ackTimeoutMillis = ackTimeoutMillis; return this; } /** * @return the configured subscription type */ public SubscriptionType getSubscriptionType() { return this.subscriptionType; } /** * Select the subscription type to be used when subscribing to the topic. * <p> * Default is {@link SubscriptionType#Exclusive} * * @param subscriptionType * the subscription type value */ public ConsumerConfiguration setSubscriptionType(SubscriptionType subscriptionType) { checkNotNull(subscriptionType); this.subscriptionType = subscriptionType; return this; } /** * @return the configured {@link MessageListener} for the consumer */ public MessageListener getMessageListener() { return this.messageListener; } /** * Sets a {@link MessageListener} for the consumer * <p> * When a {@link MessageListener} is set, application will receive messages through it. Calls to * {@link Consumer#receive()} will not be allowed. * * @param messageListener * the listener object */ public ConsumerConfiguration setMessageListener(MessageListener messageListener) { checkNotNull(messageListener); this.messageListener = messageListener; return this; } /** * @return the configure receiver queue size value */ public int getReceiverQueueSize() { return this.receiverQueueSize; } /** * Sets the size of the consumer receive queue. * <p> * The consumer receive queue controls how many messages can be accumulated by the {@link Consumer} before the * application calls {@link Consumer#receive()}. Using a higher value could potentially increase the consumer * throughput at the expense of bigger memory utilization. * </p> * <p> * <b>Setting the consumer queue size as zero</b> * <ul> * <li>Decreases the throughput of the consumer, by disabling pre-fetching of messages. This approach improves the * message distribution on shared subscription, by pushing messages only to the consumers that are ready to process * them. Neither {@link Consumer#receive(int, TimeUnit)} nor Partitioned Topics can be used if the consumer queue * size is zero. {@link Consumer#receive()} function call should not be interrupted when the consumer queue size is * zero.</li> * <li>Doesn't support Batch-Message: if consumer receives any batch-message then it closes consumer connection with * broker and {@link Consumer#receive()} call will remain blocked while {@link Consumer#receiveAsync()} receives * exception in callback. <b> consumer will not be able receive any further message unless batch-message in pipeline * is removed</b></li> * </ul> * </p> * Default value is {@code 1000} messages and should be good for most use cases. * * @param receiverQueueSize * the new receiver queue size value */ public ConsumerConfiguration setReceiverQueueSize(int receiverQueueSize) { checkArgument(receiverQueueSize >= 0, "Receiver queue size cannot be negative"); this.receiverQueueSize = receiverQueueSize; return this; } /** * @return the consumer name */ public String getConsumerName() { return consumerName; } /** * Set the consumer name. * * @param consumerName */ public ConsumerConfiguration setConsumerName(String consumerName) { checkArgument(consumerName != null && !consumerName.equals("")); this.consumerName = consumerName; return this; } public int getPriorityLevel() { return priorityLevel; } /** * Sets priority level for the shared subscription consumers to which broker gives more priority while dispatching * messages. Here, broker follows descending priorities. (eg: 0=max-priority, 1, 2,..) </br> * In Shared subscription mode, broker will first dispatch messages to max priority-level consumers if they have * permits, else broker will consider next priority level consumers. </br> * If subscription has consumer-A with priorityLevel 0 and Consumer-B with priorityLevel 1 then broker will dispatch * messages to only consumer-A until it runs out permit and then broker starts dispatching messages to Consumer-B. * * <pre> * Consumer PriorityLevel Permits * C1 0 2 * C2 0 1 * C3 0 1 * C4 1 2 * C5 1 1 * Order in which broker dispatches messages to consumers: C1, C2, C3, C1, C4, C5, C4 * </pre> * * @param priorityLevel */ public void setPriorityLevel(int priorityLevel) { this.priorityLevel = priorityLevel; } }