io.nats.client.BaseConsumeOptions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jnats Show documentation
Show all versions of jnats Show documentation
Client library for working with the NATS messaging system.
// Copyright 2023 The NATS Authors
// 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 io.nats.client;
import io.nats.client.api.ConsumerConfiguration;
import io.nats.client.support.JsonParseException;
import io.nats.client.support.JsonParser;
import io.nats.client.support.JsonSerializable;
import io.nats.client.support.JsonValue;
import static io.nats.client.support.ApiConstants.*;
import static io.nats.client.support.JsonUtils.*;
import static io.nats.client.support.JsonValueUtils.readBoolean;
import static io.nats.client.support.JsonValueUtils.readInteger;
import static io.nats.client.support.JsonValueUtils.readLong;
/**
* Base Consume Options are provided to customize the way the consume and
* fetch operate. It is the base class for ConsumeOptions and FetchConsumeOptions.
*/
public class BaseConsumeOptions implements JsonSerializable {
public static final int DEFAULT_MESSAGE_COUNT = 500;
public static final int DEFAULT_MESSAGE_COUNT_WHEN_BYTES = 1_000_000;
public static final int DEFAULT_THRESHOLD_PERCENT = 25;
public static final long DEFAULT_EXPIRES_IN_MILLIS = 30000;
public static final long MIN_EXPIRES_MILLS = 1000;
public static final long MAX_HEARTBEAT_MILLIS = 30000;
public static final int MAX_IDLE_HEARTBEAT_PERCENT = 50;
protected final int messages;
protected final long bytes;
protected final long expiresIn;
protected final long idleHeartbeat;
protected final int thresholdPercent;
protected final boolean noWait;
@SuppressWarnings("rawtypes") // Don't need the type of the builder to get its vars
protected BaseConsumeOptions(Builder b) {
bytes = b.bytes;
if (bytes > 0) {
messages = b.messages == -1 ? DEFAULT_MESSAGE_COUNT_WHEN_BYTES : b.messages;
}
else {
messages = b.messages == -1 ? DEFAULT_MESSAGE_COUNT : b.messages;
}
// validation handled in builder
thresholdPercent = b.thresholdPercent;
noWait = b.noWait;
// if it's not noWait, it must have an expiresIn
// we can't check this in the builder because we can't guarantee order
// so we always default to LONG_UNSET in the builder and check it here.
if (b.expiresIn == ConsumerConfiguration.LONG_UNSET && !noWait) {
expiresIn = DEFAULT_EXPIRES_IN_MILLIS;
}
else {
expiresIn = b.expiresIn;
}
// calculated
idleHeartbeat = Math.min(MAX_HEARTBEAT_MILLIS, expiresIn * MAX_IDLE_HEARTBEAT_PERCENT / 100);
}
@Override
public String toJson() {
StringBuilder sb = beginJson();
addField(sb, MESSAGES, messages);
addField(sb, BYTES, bytes);
addField(sb, EXPIRES_IN, expiresIn);
addField(sb, IDLE_HEARTBEAT, idleHeartbeat);
addField(sb, THRESHOLD_PERCENT, thresholdPercent);
addFldWhenTrue(sb, NO_WAIT, noWait);
return endJson(sb).toString();
}
public long getExpiresInMillis() {
return expiresIn;
}
public long getIdleHeartbeat() {
return idleHeartbeat;
}
public int getThresholdPercent() {
return thresholdPercent;
}
public boolean isNoWait() {
return noWait;
}
protected static abstract class Builder {
protected int messages = -1;
protected long bytes = 0;
protected int thresholdPercent = DEFAULT_THRESHOLD_PERCENT;
protected long expiresIn = DEFAULT_EXPIRES_IN_MILLIS;
protected boolean noWait = false;
protected abstract B getThis();
protected B noWait() {
return getThis();
}
/**
* Initialize values from the json string.
* @param json the json string to parse
* @return the builder
* @throws JsonParseException if the json is invalid
*/
public B json(String json) throws JsonParseException {
return jsonValue(JsonParser.parse(json));
}
/**
* Initialize values from the JsonValue object.
* @param jsonValue the json value object
* @return the builder
*/
public B jsonValue(JsonValue jsonValue) {
messages(readInteger(jsonValue, MESSAGES, -1));
bytes(readLong(jsonValue, BYTES, -1));
expiresIn(readLong(jsonValue, EXPIRES_IN, MIN_EXPIRES_MILLS));
thresholdPercent(readInteger(jsonValue, THRESHOLD_PERCENT, -1));
if (readBoolean(jsonValue, NO_WAIT, false)) {
noWait();
}
return getThis();
}
protected B messages(int messages) {
this.messages = messages < 1 ? -1 : messages;
return getThis();
}
protected B bytes(long bytes) {
this.bytes = bytes < 1 ? 0 : bytes;
return getThis();
}
/**
* In Fetch, sets the maximum amount of time to wait to reach the batch size or max byte.
* In Consume, sets the maximum amount of time for an individual pull to be open
* before issuing a replacement pull.
* Zero or less will default to {@value BaseConsumeOptions#DEFAULT_EXPIRES_IN_MILLIS},
* otherwise, cannot be less than {@value BaseConsumeOptions#MIN_EXPIRES_MILLS}
* @param expiresInMillis the expiration time in milliseconds
* @return the builder
*/
public B expiresIn(long expiresInMillis) {
if (expiresInMillis < 1) { // this is way to clear or reset, just a code guard really
expiresIn = ConsumerConfiguration.LONG_UNSET;
}
else if (expiresInMillis < MIN_EXPIRES_MILLS) {
throw new IllegalArgumentException("Expires must be greater than or equal to " + MIN_EXPIRES_MILLS);
}
else {
expiresIn = expiresInMillis;
}
return getThis();
}
/**
* Set the threshold percent of max bytes (if max bytes is specified) or messages
* that will trigger issuing pull requests to keep messages flowing.
* Only applies to endless consumes.
* For instance if the batch size is 100 and the re-pull percent is 25,
* the first pull will be for 100, and then when 25 messages have been received
* another 75 will be requested, keeping the number of messages in transit always at 100.
* Must be between 1 and 100 inclusive.
* Less than 1 will assume the default of {@value BaseConsumeOptions#DEFAULT_THRESHOLD_PERCENT}.
* Greater than 100 will assume 100.
* @param thresholdPercent the threshold percent
* @return the builder
*/
public B thresholdPercent(int thresholdPercent) {
this.thresholdPercent = thresholdPercent < 1 ? DEFAULT_THRESHOLD_PERCENT : Math.min(100, thresholdPercent);
return getThis();
}
/**
* Build the options.
* @return the built options
*/
public abstract CO build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy