Class LoomClient
- All Implemented Interfaces:
AutoCloseable
Client Routing
DefaultClientRoutingMode.ALL_MEMBERS maintains connections to all configured seeds
and routes requests across active members. ClientRoutingMode.SINGLE_MEMBER keeps one
member connection for environments that restrict outbound sockets.
ClientRoutingMode.MULTI_MEMBER keeps smart routing within a configured member group.
Near Cache
Frequently accessed entries may be cached locally when near cache is enabled. GET checks near cache first. Invalidated on PUT/DELETE. Configurable TTL and max size.Connection Management
- Connects to all seeds on startup
- Exponential backoff (100ms → 5s cap) + jitter (±25%) on connection retry
- Request-response correlation via correlation IDs
- Thread-safe: synchronized + ReentrantLock where appropriate (JEP 491 safe on Java 25+)
Retry Behavior
Failed requests are retried up to maxRetries times (default 3).
Between retries, the client applies exponential backoff: delay = min(100ms × 2^attempt, 5000ms),
with ±25% jitter added to prevent thundering herd effects.
During leader election, when no leader is available, the client transparently cycles through all known nodes (round-robin) and retries every 100ms for up to 15 seconds. This wait period does not count against the retry limit.
Redirect Handling (Consistency-by-default)
When the server responds with RESPONSE_REDIRECT, the client:
- Extracts the leader address from the response
- Caches it for future requests
- Retries immediately on the leader (or waits if election is in progress)
Request Timeout
Each operation has an individual timeout (default 120 seconds) that applies to the request-response exchange with the server. Timeouts are not retried; they are treated as fatal errors and trigger exponential backoff on the next retry attempt.
Usage
LoomClient client = LoomClient.builder()
.addSeed("127.0.0.1:5701")
.addSeed("127.0.0.1:5702")
.connectionTimeout(Duration.ofSeconds(5))
.requestTimeout(Duration.ofSeconds(120))
.maxRetries(3)
.nearCacheEnabled(true)
.nearCacheTtl(Duration.ofSeconds(30))
.build();
client.connect();
// Map operations
client.mapPut("users", "user1", "john");
String value = client.mapGet("users", "user1");
// Queue operations
client.queuePush("tasks", "process_order_123");
String task = client.queuePop("tasks");
// Set operations
client.setAdd("tags", "trending");
Set<String> tags = client.setMembers("tags");
// Cleanup
client.close();
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classstatic interfaceListener interface for receiving entry events from the cache. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedLoomClient(LoomClient.Builder builder) LoomClient(List<String> seedAddresses) Deprecated, for removal: This API element is subject to removal in a future version. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddIndex(String mapName, IndexConfig config) Adds or replaces index metadata for a distributed map through the SQL DDL path.addLifecycleListener(LifecycleListener listener) addMembershipListener(MembershipListener listener) async()Create an async wrapper for this client using CompletableFuture.booleanlongatomicLongAddAndGet(String atomicLongName, long delta) Atomically add a delta to an atomic long and return the new value.booleanatomicLongCompareAndSet(String atomicLongName, long expectedValue, long newValue) Atomically compare and set an atomic long.longatomicLongDecrementAndGet(String atomicLongName) Atomically decrement an atomic long and return the new value.longatomicLongGet(String atomicLongName) Get the current value of an atomic long.longatomicLongGetAndAdd(String atomicLongName, long delta) Atomically get the current value and add a delta.longatomicLongGetAndDecrement(String atomicLongName) Atomically get the current value and decrement.longatomicLongGetAndIncrement(String atomicLongName) Atomically get the current value and increment.longatomicLongIncrementAndGet(String atomicLongName) Atomically increment an atomic long and return the new value.voidatomicLongSet(String atomicLongName, long value) Set the value of an atomic long.booleanatomicReferenceCompareAndSet(String refName, @Nullable Object expectedValue, @Nullable Object newValue) <T> @Nullable TatomicReferenceGet(String refName, Class<T> type) voidatomicReferenceSet(String refName, @Nullable Object value) batch()Create a newLoomBatchfor batching multiple data-structure operations into a single server-side execution.static LoomClient.Builderbuilder()voidvoidclose()Close the client and release all resources.voidconnect()Establish connections to seed nodes in the cluster.intAccess the Consistency Subsystem for strongly consistent primitives.voidderegisterCqcListener(String mapName, LoomClient.MapChangeListener listener) Remove a previously registered CQC listener and deliverMessageType.CQC_UNSUBSCRIBEto every connected node.voidderegisterLocalMapListener(String mapName, LoomClient.MapChangeListener listener) Deregister a local-only map listener.voidderegisterMapListener(String mapName, LoomClient.MapChangeListener listener) Unregister a listener for entry events on a specific map.intevaluatePoolScaling(String nodeId, int activeConnections, int totalConnections) Monitor and evaluate auto-scaling metrics for a node's connection pool.JavaBean-style alias forconsistencySubsystem().getExecutorService(String name) Obtain a handle to a named distributed executor service.<E> LoomGSet<E> Obtain a handle to a grow-only set CRDT.getIdGenerator(String name) Obtain a distributed Snowflake ID generator without client-side prefetch.getIdGenerator(String name, int prefetchCount, long prefetchValidityMillis) Obtain a distributed Snowflake ID generator with client-side prefetch.<E> LoomList<E> Obtain a handle to a distributed list.<V> LoomLWWRegister<V> getLWWRegister(String name) Obtain a handle to a last-writer-wins register CRDT.<K,V> LoomMap <K, V> Obtain a type-safe handle to a distributed map.<K,V> LoomMultiMap <K, V> getMultiMap(String name) Obtain a handle to a distributed multimap.Get the current near-cache invalidation mode.int<E> LoomORSet<E> Obtain a handle to an observed-remove set CRDT.getPNCounter(String name) Obtain a session-bound PN-counter handle.<E> LoomPriorityQueue<E> getPriorityQueue(String name) Obtain a handle to a distributed priority queue.<E> LoomQueue<E> Obtain a handle to a distributed queue.<T> LoomReliableTopic<T> getReliableTopic(String name) Obtain a handle to a reliable topic.<T> LoomReliableTopic<T> getReliableTopic(String name, int capacity, TopicOverloadPolicy policy) Obtain a handle to a reliable topic with explicit retention capacity and overload policy.<E> LoomRingbuffer<E> getRingbuffer(String name) Obtain a handle to a distributed ringbuffer.<E> LoomRingbuffer<E> getRingbuffer(String name, int capacity) Obtain a handle to a distributed ringbuffer with an explicit creation capacity.<E> LoomSet<E> Obtain a handle to a distributed set.Obtain a handle to a distributed topic withStringmessages.<T> LoomTopic<T> Obtain a typed handle to a distributed topic.booleanbooleangSetContains(String setName, String element) gSetMembers(String setName) intlongidGeneratorNext(String generatorName) idGeneratorNextBatch(String generatorName, int count) booleanbooleanbooleanvoidlatchAwait(String latchName) booleanlatchAwait(String latchName, Duration timeout) voidlatchCountDown(String latchName) longlatchGetCount(String latchName) booleanlatchTrySetCount(String latchName, long count) booleanvoid@Nullable String@Nullable StringlistRemove(String listName, int index) @Nullable StringintlistSubList(String listName, int fromIndex, int toIndex) static LoomClientlocalhost(int port) Create a client connecting to localhost on the specified port.longlockAcquire(String lockName) Acquire a linearizable lock, blocking until successful.longlockAcquireAndGetFence(String lockName) Acquire the lock and return the fence token.longlockGetFence(String lockName) Deprecated, for removal: This API element is subject to removal in a future version.UselockAcquire(String)instead.voidlockRelease(String lockName) Release a linearizable lock.longlockTryAcquire(String lockName, Duration timeout) Try to acquire a linearizable lock with timeout.@Nullable StringlonglonglwwTimestamp(String registerName) voidbooleanmapCompareDelete(String mapName, String key, String expectedValue) booleanmapContainsKey(String mapName, String key) booleanmapContainsKeyWithTimeout(String mapName, String key, Duration timeout) Check if a key exists with per-operation timeout override.boolean@Nullable StringmapDeleteAndGet(String mapName, String key) Atomically remove a key and return the previously associated value.booleanmapDeleteWithTimeout(String mapName, String key, Duration timeout) Delete a key-value pair with per-operation timeout override.<R> @Nullable RmapExecuteOnKey(String mapName, String key, EntryProcessor<?, ?, R> processor) @Nullable StringGet a value from a distributed map.@Nullable StringmapGetWithTimeout(String mapName, String key, Duration timeout) Get a key-value pair with per-operation timeout override.@Nullable StringPut a key-value pair into a distributed map.@Nullable StringmapPutIfAbsent(String mapName, String key, String value) Atomically put a key-value pair only if the key is not already present.@Nullable StringmapPutWithTimeout(String mapName, String key, String value, Duration timeout) Put a key-value pair with per-operation timeout override.@Nullable StringmapPutWithTtl(String mapName, String key, String value, long ttl, TimeUnit timeUnit) Store a key-value pair with server-owned entry TTL.@Nullable StringmapPutWithTtl(String mapName, String key, String value, Duration ttl) Store a key-value pair with server-owned entry TTL.@Nullable StringmapReplace(String mapName, String key, String value) booleanmapReplaceCas(String mapName, String key, String oldValue, String newValue) intvoidmultiMapClear(String mapName) multiMapGet(String mapName, String key) multiMapKeys(String mapName) booleanmultiMapPut(String mapName, String key, String value) booleanmultiMapRemove(String mapName, String key, String value) intmultiMapSize(String mapName) multiMapValues(String mapName) booleanBegin a new server-side transaction with the default timeout.newTransaction(@Nullable Duration timeout) Begin a new server-side transaction with an explicit timeout.booleanbooleanorSetContains(String setName, String element) orSetMembers(String setName) booleanorSetRemove(String setName, String element) intlongpnCounterAddAndGet(String counterName, long delta, String sessionId, long epoch) longpnCounterDecrementAndGet(String counterName, String sessionId, long epoch) longpnCounterGet(String counterName, String sessionId, long epoch) longpnCounterIncrementAndGet(String counterName, String sessionId, long epoch) longpnCounterResetSession(String counterName, String sessionId) longpnCounterSubtractAndGet(String counterName, long delta, String sessionId, long epoch) voidpriorityQueueClear(String queueName) booleanpriorityQueueOffer(String queueName, String item) booleanpriorityQueueOffer(String queueName, String item, int priority) @Nullable StringpriorityQueuePeek(String queueName) @Nullable StringpriorityQueuePoll(String queueName) longpriorityQueueSize(String queueName) queueDrain(String queueName) Drain the queue into a list.queueDrainTo(String queueName, int maxElements) Remove up tomaxElementsitems from the head of a distributed FIFO queue.booleanqueueOffer(String queueName, String item) Enqueue an item at the tail of a distributed FIFO queue.intqueueOfferAll(String queueName, Collection<String> items) Enqueue multiple items at the tail of a distributed FIFO queue.booleanqueueOfferWithTimeout(String queueName, String item, Duration timeout) Enqueue an item with per-operation timeout override.@Nullable StringPeek at the head of a distributed queue without removing it.@Nullable StringDequeue an item from the head of a distributed FIFO queue.queuePollN(String queueName, int count) Remove up tocountitems from the head of a distributed FIFO queue.@Nullable StringqueuePollWithTimeout(String queueName, Duration timeout) Dequeue an item with per-operation timeout override.intReturn the number of items currently in a distributed FIFO queue.booleanregisterClass(Class<?> clazz, int id) Register an application class with this client's Kryo serializer.<T> LoomClientregisterClass(Class<T> clazz, int id, com.esotericsoftware.kryo.Serializer<? super T> serializer) Register an application class with a class-specific Kryo serializer.voidregisterCqcListener(String mapName, LoomClient.MapChangeListener listener, SerializablePredicate predicate) Register a CQC-filtered event listener for the given map.voidregisterLocalMapListener(String mapName, LoomClient.MapChangeListener listener) Register an entry listener on exactly one connected member.voidregisterMapListener(String mapName, LoomClient.MapChangeListener listener) Register a listener for entry events on a specific map.longreliableTopicPublish(String topicName, String message, TopicOverloadPolicy policy, int capacity) reliableTopicReadFrom(String topicName, long fromSequence, int maxCount) voidreliableTopicUnsubscribe(String topicName) booleanbooleanremoveLifecycleListener(LifecycleListener listener) booleanremoveMembershipListener(MembershipListener listener) longringbufferAdd(String ringbufferName, String item, int capacity) intringbufferCapacity(String ringbufferName) longringbufferHeadSequence(String ringbufferName) ringbufferReadMany(String ringbufferName, long startSequence, int maxCount) @Nullable StringringbufferReadOne(String ringbufferName, long sequence) longringbufferTailSequence(String ringbufferName) @Nullable StringvoidsemaphoreAcquire(String semaphoreName, int permits) Acquire permits from a semaphore, blocking if necessary.intsemaphoreAvailablePermits(String semaphoreName) Get the number of available permits in a semaphore.voidsemaphoreRelease(String semaphoreName, int permits) Release permits to a semaphore.booleansemaphoreTryAcquire(String semaphoreName, int permits, Duration timeout) Try to acquire permits from a semaphore with timeout.booleanAdd an element to a distributed set.booleansetAddWithTimeout(String setName, String element, Duration timeout) Add an element to a distributed set with per-operation timeout override.voidbooleansetContains(String setName, String element) Check if a distributed set contains an element.booleansetContainsWithTimeout(String setName, String element, Duration timeout) Check if a distributed set contains an element with per-operation timeout override.voidsetNearCacheEnabled(boolean enabled) voidvoidvoidsetNearCacheMaxSize(int maxSize) voidvoidvoidsetNearCacheSerializeKeys(boolean serializeKeys) voidsetNearCacheTtlMs(long ttlMs) Change the TTL for new near cache entries.booleanRemove an element from a distributed set.booleansetRemoveWithTimeout(String setName, String element, Duration timeout) Remove an element from a distributed set with per-operation timeout override.setScan(long cursor) Deprecated, for removal: This API element is subject to removal in a future version.UsesetScan(String, long, String, int)with explicit set nameintGet the number of elements in a distributed set.Execute a SQL query on the cluster.@Nullable StringPoll for a message from a topic (client-side polling for subscriptions).voidtopicPublish(String message) Deprecated, for removal: This API element is subject to removal in a future version.UsetopicPublish(String, String)with explicit topic namevoidtopicPublish(String topicName, String message) Publish a message to a distributed topic.voidtopicPublishWithTimeout(String topicName, String message, Duration timeout) Publish a message to a distributed topic with per-operation timeout override.
-
Constructor Details
-
LoomClient
-
LoomClient
Deprecated, for removal: This API element is subject to removal in a future version.Usebuilder()instead for better control and clarityLegacy constructor for backward compatibility.Prefer using
builder()for more explicit configuration. Uses default timeouts and retry settings: - Connection timeout: 5000ms - Request timeout: 10000ms - Max retries: 3 - Near cache: enabled with 30s TTL and 10000 max entries- Parameters:
seedAddresses- the list of seed addresses (must not be empty)- Throws:
IllegalArgumentException- if seedAddresses is empty
-
-
Method Details
-
builder
-
localhost
Create a client connecting to localhost on the specified port. For development/testing. -
connect
public void connect()Establish connections to seed nodes in the cluster.In
ClientRoutingMode.ALL_MEMBERS, this method connects to each seed address in order. InClientRoutingMode.SINGLE_MEMBER, it stops after the first successful seed connection. InClientRoutingMode.MULTI_MEMBER, it connects only to seeds that match the configured member-group IP/CIDR rules. Failed connections are logged but do not block; at least one successful connection is required for subsequent operations to succeed. Seed addresses must be in the format "host:port".If the client was configured with authentication (via
builder().auth(username, roles)orbuilder().credentialsFactory(factory)), an AUTH message is automatically sent to all connected nodes after successful connection.This method is idempotent: calling it multiple times has no effect after the first call.
- Throws:
IllegalArgumentException- if a seed address has invalid format
-
close
public void close()Close the client and release all resources.This method:
- Closes all socket connections to cluster nodes
- Clears the near cache
- Completes all pending requests with an IOException
- Marks the client as closed
After closing, all subsequent operations will fail. This method is idempotent: calling it multiple times has no side effects.
For use in try-with-resources:
try (LoomClient client = LoomClient.builder().addSeed("127.0.0.1:5701").build()) { client.connect(); // use client } // automatically closed- Specified by:
closein interfaceAutoCloseable
-
refreshPartitionTable
public boolean refreshPartitionTable() -
mapGet
Get a value from a distributed map.This operation is routed via smart routing (key hash) to the primary owner node, avoiding an extra network hop. The near cache is checked first if enabled.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes. During leader elections, the client waits transparently for up to 15 seconds.- Parameters:
mapName- the name of the map (must not be null or empty)key- the key to retrieve (must not be null or empty)- Returns:
- the value associated with the key, or null if not found
- Throws:
LoomException- if the operation fails after all retries, or on timeout
-
mapPut
Put a key-value pair into a distributed map.This operation is routed to the leader (for write consistency) after caching the leader address from redirects. If no leader is available, the client waits transparently during leader elections.
The near cache entry for this key is invalidated to prevent serving stale data.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
mapName- the name of the map (must not be null or empty)key- the key to set (must not be null or empty)value- the value to set (must not be null)- Returns:
- the previous value associated with the key, or null if the key was not present
- Throws:
LoomException- if the operation fails after all retries, or on timeout
-
mapPutWithTtl
public @Nullable String mapPutWithTtl(String mapName, String key, String value, Duration ttl) throws LoomException Store a key-value pair with server-owned entry TTL.This TTL controls the map entry lifetime. It is intentionally separate from per-request timeout APIs such as
mapPutWithTimeout(String, String, String, Duration). A negative TTL means use the map default TTL, if any; zero means no explicit entry expiry.- Throws:
LoomException
-
mapPutWithTtl
public @Nullable String mapPutWithTtl(String mapName, String key, String value, long ttl, TimeUnit timeUnit) throws LoomException Store a key-value pair with server-owned entry TTL.- Parameters:
ttl- entry TTL intimeUnit; negative means use the map default TTL, if any; zero means no explicit entry expiry- Throws:
LoomException
-
mapPutIfAbsent
public @Nullable String mapPutIfAbsent(String mapName, String key, String value) throws LoomException Atomically put a key-value pair only if the key is not already present.Server executes
MAP_PUT_IF_ABSENT(0x08) atomically viaDistributedMap.putIfAbsent()— no race window between check and insert.- Parameters:
mapName- the name of the map (must not be null or empty)key- the key to set (must not be null or empty)value- the value to set (must not be null)- Returns:
- the existing value if the key was already present, or null if the key was inserted
- Throws:
LoomException- if the operation fails after all retries, or on timeout
-
mapReplace
- Throws:
LoomException
-
mapReplaceCas
public boolean mapReplaceCas(String mapName, String key, String oldValue, String newValue) throws LoomException - Throws:
LoomException
-
mapCompareDelete
public boolean mapCompareDelete(String mapName, String key, String expectedValue) throws LoomException - Throws:
LoomException
-
mapDelete
- Throws:
LoomException
-
mapExecuteOnKey
public <R> @Nullable R mapExecuteOnKey(String mapName, String key, EntryProcessor<?, ?, throws LoomExceptionR> processor) - Throws:
LoomException
-
mapDeleteAndGet
Atomically remove a key and return the previously associated value.Unlike
mapDelete(String, String), which discards the server response payload, this variant surfaces the deleted value directly from the single round-tripMAP_DELETEresponse. That guarantees destructive-read semantics: the value returned here is exactly what the server removed, with no get-then-delete race against concurrent writers.- Parameters:
mapName- target mapkey- key to remove- Returns:
- the previous value associated with
key, ornullif the key was not present - Throws:
LoomException- if the operation fails
-
mapContainsKey
-
mapClear
- Throws:
LoomException
-
mapSize
-
mapScan
public ScanResult mapScan(String mapName, long cursor, @Nullable String pattern, int count) throws Exception - Throws:
Exception
-
mapGetWithTimeout
public @Nullable String mapGetWithTimeout(String mapName, String key, Duration timeout) throws LoomException Get a key-value pair with per-operation timeout override.- Parameters:
mapName- the name of the mapkey- the key to look uptimeout- per-operation timeout; if null, uses client's default- Returns:
- the value associated with the key, or null if not found
- Throws:
LoomException- if the operation fails or times out
-
mapPutWithTimeout
public @Nullable String mapPutWithTimeout(String mapName, String key, String value, Duration timeout) throws LoomException Put a key-value pair with per-operation timeout override.- Parameters:
mapName- the name of the mapkey- the key to storevalue- the value to associate with the keytimeout- per-operation timeout; if null, uses client's default- Returns:
- the previous value, or null if the key was not present
- Throws:
LoomException- if the operation fails or times out
-
mapDeleteWithTimeout
public boolean mapDeleteWithTimeout(String mapName, String key, Duration timeout) throws LoomException Delete a key-value pair with per-operation timeout override.- Parameters:
mapName- the name of the mapkey- the key to removetimeout- per-operation timeout; if null, uses client's default- Returns:
- true if the key was present and removed; false if the key was not found
- Throws:
LoomException- if the operation fails or times out
-
mapContainsKeyWithTimeout
public boolean mapContainsKeyWithTimeout(String mapName, String key, Duration timeout) throws LoomException Check if a key exists with per-operation timeout override.- Parameters:
mapName- the name of the mapkey- the key to check fortimeout- per-operation timeout; if null, uses client's default- Returns:
- true if the key exists; false otherwise
- Throws:
LoomException- if the operation fails or times out
-
queueOffer
Enqueue an item at the tail of a distributed FIFO queue.The item is appended to the queue and persisted. If the queue does not exist, it is created automatically.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
queueName- the name of the queue (must not be null or empty)item- the item to enqueue (must not be null)- Returns:
- true if the item was successfully enqueued, false otherwise
- Throws:
Exception- if the operation fails after all retries
-
queuePoll
Dequeue an item from the head of a distributed FIFO queue.Removes and returns the first item in the queue. If the queue is empty, returns null.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
queueName- the name of the queue (must not be null or empty)- Returns:
- the first item in the queue, or null if the queue is empty
- Throws:
Exception- if the operation fails after all retries
-
queuePeek
Peek at the head of a distributed queue without removing it.Returns the first item in the queue without modifying the queue. If the queue is empty, returns null.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
queueName- the name of the queue (must not be null or empty)- Returns:
- the first item in the queue, or null if the queue is empty
- Throws:
Exception- if the operation fails after all retries
-
queueSize
Return the number of items currently in a distributed FIFO queue.- Parameters:
queueName- the name of the queue (must not be null or empty)- Returns:
- queue size, or 0 when the queue does not exist
- Throws:
Exception- if the operation fails after all retries
-
queueOfferAll
Enqueue multiple items at the tail of a distributed FIFO queue.- Parameters:
queueName- the name of the queue (must not be null or empty)items- items to enqueue (must not be null and must not contain nulls)- Returns:
- number of items accepted by the queue
- Throws:
Exception- if the operation fails after all retries
-
queuePollN
Remove up tocountitems from the head of a distributed FIFO queue.- Parameters:
queueName- the name of the queue (must not be null or empty)count- maximum number of items to remove- Returns:
- removed items in FIFO order; empty when the queue does not exist
- Throws:
Exception- if the operation fails after all retries
-
queueDrainTo
Remove up tomaxElementsitems from the head of a distributed FIFO queue.- Parameters:
queueName- the name of the queue (must not be null or empty)maxElements- maximum number of items to remove- Returns:
- removed items in FIFO order; empty when the queue does not exist
- Throws:
Exception- if the operation fails after all retries
-
queueDrain
Drain the queue into a list.- Parameters:
queueName- the name of the queue (must not be null or empty)- Returns:
- removed items in FIFO order; empty when the queue does not exist
- Throws:
Exception- if the operation fails after all retries
-
queueOfferWithTimeout
public boolean queueOfferWithTimeout(String queueName, String item, Duration timeout) throws LoomException Enqueue an item with per-operation timeout override.- Parameters:
queueName- the name of the queueitem- the item to enqueuetimeout- per-operation timeout; if null, uses client's default- Returns:
- true if the item was successfully enqueued, false otherwise
- Throws:
LoomException- if the operation fails or times out
-
queuePollWithTimeout
public @Nullable String queuePollWithTimeout(String queueName, Duration timeout) throws LoomException Dequeue an item with per-operation timeout override.- Parameters:
queueName- the name of the queuetimeout- per-operation timeout; if null, uses client's default- Returns:
- the first item in the queue, or null if the queue is empty
- Throws:
LoomException- if the operation fails or times out
-
multiMapPut
-
multiMapGet
-
multiMapRemove
-
multiMapSize
-
multiMapKeys
-
multiMapValues
-
multiMapClear
-
listAdd
-
listGet
-
listSet
-
listRemove
-
listSize
-
listSubList
-
listClear
-
priorityQueueOffer
-
priorityQueueOffer
-
priorityQueuePoll
-
priorityQueuePeek
-
priorityQueueSize
-
priorityQueueClear
-
ringbufferAdd
-
ringbufferReadOne
-
ringbufferReadMany
-
ringbufferHeadSequence
-
ringbufferTailSequence
-
ringbufferCapacity
-
reliableTopicPublish
public long reliableTopicPublish(String topicName, String message, TopicOverloadPolicy policy, int capacity) throws Exception - Throws:
Exception
-
reliableTopicReadFrom
-
reliableTopicUnsubscribe
-
pnCounterResetSession
-
pnCounterGet
-
pnCounterIncrementAndGet
-
pnCounterDecrementAndGet
-
pnCounterAddAndGet
-
pnCounterSubtractAndGet
-
gSetAdd
-
gSetContains
-
gSetSize
-
gSetMembers
-
orSetAdd
-
orSetRemove
-
orSetContains
-
orSetSize
-
orSetMembers
-
lwwGet
-
lwwSet
-
lwwTimestamp
-
idGeneratorNext
-
idGeneratorNextBatch
-
topicPublish
-
topicPublishWithTimeout
public void topicPublishWithTimeout(String topicName, String message, Duration timeout) throws LoomException Publish a message to a distributed topic with per-operation timeout override.- Parameters:
topicName- the name of the topicmessage- the message to publishtimeout- per-operation timeout; if null, uses the client's default timeout- Throws:
LoomException- if the operation fails or times out
-
topicPublish
Deprecated, for removal: This API element is subject to removal in a future version.UsetopicPublish(String, String)with explicit topic name- Throws:
Exception
-
topicPoll
Poll for a message from a topic (client-side polling for subscriptions).This is a simple polling mechanism used by LoomTopic.subscribe() to fetch messages at regular intervals. For production use, server-push is preferred.
- Parameters:
topicName- the name of the topicsequenceId- the last seen sequence ID (used to avoid duplicates)- Returns:
- the message if available, null if no new messages
- Throws:
Exception- on network errors
-
setAdd
Add an element to a distributed set.If the element already exists in the set, no change occurs. The operation is routed via smart routing to the node owning this element.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
setName- the name of the set (must not be null or empty)element- the element to add (must not be null)- Returns:
- true if the element was added, false if it was already present
- Throws:
Exception- if the operation fails after all retries
-
setRemove
Remove an element from a distributed set.If the element is not present, no change occurs. The operation is routed via smart routing to the node owning this element.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
setName- the name of the set (must not be null or empty)element- the element to remove (must not be null)- Returns:
- true if the element was removed, false if it was not present
- Throws:
Exception- if the operation fails after all retries
-
setContains
Check if a distributed set contains an element.The operation is routed via smart routing to the node owning this element. Results are not cached in the near cache.
Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
setName- the name of the set (must not be null or empty)element- the element to check (must not be null)- Returns:
- true if the set contains the element, false otherwise
- Throws:
Exception- if the operation fails after all retries
-
setSize
Get the number of elements in a distributed set.Failures are transparently retried with exponential backoff (100ms → 5s) up to
maxRetriestimes.- Parameters:
setName- the name of the set (must not be null or empty)- Returns:
- the number of elements in the set, or 0 if the set does not exist
- Throws:
Exception- if the operation fails after all retries
-
setClear
-
setScan
public ScanResult setScan(String setName, long cursor, @Nullable String pattern, int count) throws Exception - Throws:
Exception
-
setScan
Deprecated, for removal: This API element is subject to removal in a future version.UsesetScan(String, long, String, int)with explicit set name- Throws:
Exception
-
setAddWithTimeout
public boolean setAddWithTimeout(String setName, String element, Duration timeout) throws LoomException Add an element to a distributed set with per-operation timeout override.- Parameters:
setName- the name of the setelement- the element to addtimeout- per-operation timeout; if null, uses client's default- Returns:
- true if the element was added, false if it was already present
- Throws:
LoomException- if the operation fails or times out
-
setRemoveWithTimeout
public boolean setRemoveWithTimeout(String setName, String element, Duration timeout) throws LoomException Remove an element from a distributed set with per-operation timeout override.- Parameters:
setName- the name of the setelement- the element to removetimeout- per-operation timeout; if null, uses client's default- Returns:
- true if the element was removed, false if it was not present
- Throws:
LoomException- if the operation fails or times out
-
setContainsWithTimeout
public boolean setContainsWithTimeout(String setName, String element, Duration timeout) throws LoomException Check if a distributed set contains an element with per-operation timeout override.- Parameters:
setName- the name of the setelement- the element to checktimeout- per-operation timeout; if null, uses client's default- Returns:
- true if the set contains the element, false otherwise
- Throws:
LoomException- if the operation fails or times out
-
lockAcquire
-
lockTryAcquire
-
lockRelease
-
lockGetFence
@Deprecated(since="1.1", forRemoval=true) public long lockGetFence(String lockName) throws Exception Deprecated, for removal: This API element is subject to removal in a future version.UselockAcquire(String)instead. This method misleadingly suggests a read-only fence query but actually acquires the lock.Acquire the lock and return the fence token.WARNING: This method acquires the lock via
CP_LOCK_ACQUIRE. There is no read-only fence query in the current protocol. If you only need to read the fence token without acquiring, this method is NOT suitable -- it will acquire the lock as a side effect. Callers must release the lock when done.- Parameters:
lockName- the name of the lock- Returns:
- the fence token from the acquisition; 0 if not acquired
- Throws:
Exception- if the operation fails
-
lockAcquireAndGetFence
Acquire the lock and return the fence token.This method sends a
CP_LOCK_ACQUIRErequest and returns the fence token from the acquisition. The caller holds the lock after this call and must release it when done.- Parameters:
lockName- the name of the lock- Returns:
- the fence token from the acquisition; 0 if not acquired
- Throws:
Exception- if the operation fails
-
semaphoreAcquire
-
semaphoreTryAcquire
public boolean semaphoreTryAcquire(String semaphoreName, int permits, Duration timeout) throws Exception Try to acquire permits from a semaphore with timeout.- Parameters:
semaphoreName- the name of the semaphorepermits- the number of permits to acquiretimeout- the timeout duration- Returns:
- true if acquired; false if timed out
- Throws:
Exception- if the operation fails
-
semaphoreRelease
-
semaphoreAvailablePermits
-
latchTrySetCount
-
latchCountDown
-
latchAwait
-
latchAwait
-
latchGetCount
-
atomicReferenceGet
-
atomicReferenceSet
-
atomicReferenceCompareAndSet
-
atomicLongGet
-
atomicLongSet
-
atomicLongIncrementAndGet
-
atomicLongDecrementAndGet
-
atomicLongGetAndIncrement
-
atomicLongGetAndDecrement
-
atomicLongAddAndGet
-
atomicLongGetAndAdd
-
atomicLongCompareAndSet
public boolean atomicLongCompareAndSet(String atomicLongName, long expectedValue, long newValue) throws Exception Atomically compare and set an atomic long.- Parameters:
atomicLongName- the name of the atomic longexpectedValue- the expected current valuenewValue- the new value- Returns:
- true if updated; false otherwise
- Throws:
Exception- if the operation fails
-
setNearCacheEnabled
public void setNearCacheEnabled(boolean enabled) -
setNearCacheTtlMs
public void setNearCacheTtlMs(long ttlMs) Change the TTL for new near cache entries. Existing entries keep their original TTL. -
setNearCacheMaxSize
public void setNearCacheMaxSize(int maxSize) -
setNearCacheEvictionPolicy
-
nearCacheEvictionPolicy
-
getNearCacheSize
public int getNearCacheSize() -
clearNearCache
public void clearNearCache() -
getNearCacheInvalidationMode
Get the current near-cache invalidation mode. Useful for metrics/observability to track if invalidation is via server-push or polling.- Returns:
- the current mode (PUSH or POLL)
-
setNearCacheLocalUpdatePolicy
-
nearCacheLocalUpdatePolicy
-
setNearCachePreloaderConfig
-
nearCachePreloaderConfig
-
nearCacheReconciliationConfig
-
setNearCacheReconciliationConfig
-
setNearCacheSerializeKeys
public void setNearCacheSerializeKeys(boolean serializeKeys) -
nearCacheSerializeKeys
public boolean nearCacheSerializeKeys() -
addLifecycleListener
-
removeLifecycleListener
-
addMembershipListener
-
removeMembershipListener
-
addDistributedObjectListener
-
removeDistributedObjectListener
-
getMap
Obtain a type-safe handle to a distributed map.Note: All keys and values are serialized to
Stringinternally viaString.valueOf(Object). The generic types provide compile-time convenience but the underlying protocol is String-based.- Parameters:
name- the map name (shared across the cluster)
-
getExecutorService
Obtain a handle to a named distributed executor service.Submitted tasks are serialized with this client's Kryo registry. Register the same task/result classes on every server node before using this API.
-
registerClass
Register an application class with this client's Kryo serializer.The same class and ID must be registered on every server node that may deserialize the payload.
-
registerClass
public <T> LoomClient registerClass(Class<T> clazz, int id, com.esotericsoftware.kryo.Serializer<? super T> serializer) Register an application class with a class-specific Kryo serializer.The same class, ID, and serializer must be registered on every server node that may deserialize the payload.
-
getQueue
Obtain a handle to a distributed queue. Same String-serialization caveat asgetMap(String). -
getMultiMap
Obtain a handle to a distributed multimap. Same String-serialization caveat asgetMap(String). -
getList
Obtain a handle to a distributed list. Same String-serialization caveat asgetMap(String). -
getPriorityQueue
Obtain a handle to a distributed priority queue. Same String-serialization caveat asgetMap(String). -
getRingbuffer
Obtain a handle to a distributed ringbuffer. Same String-serialization caveat asgetMap(String). -
getRingbuffer
Obtain a handle to a distributed ringbuffer with an explicit creation capacity. -
getReliableTopic
Obtain a handle to a reliable topic. Same String-serialization caveat asgetMap(String). -
getReliableTopic
public <T> LoomReliableTopic<T> getReliableTopic(String name, int capacity, TopicOverloadPolicy policy) Obtain a handle to a reliable topic with explicit retention capacity and overload policy. -
getPNCounter
Obtain a session-bound PN-counter handle. -
getGSet
Obtain a handle to a grow-only set CRDT. Same String-serialization caveat asgetMap(String). -
getORSet
Obtain a handle to an observed-remove set CRDT. Same String-serialization caveat asgetMap(String). -
getLWWRegister
Obtain a handle to a last-writer-wins register CRDT. Same String-serialization caveat asgetMap(String). -
getIdGenerator
Obtain a distributed Snowflake ID generator without client-side prefetch. -
getIdGenerator
Obtain a distributed Snowflake ID generator with client-side prefetch. -
getTopic
Obtain a handle to a distributed topic withStringmessages.Warning: this overload returns a String-typed topic because the default wire format is
String. For non-String message types you must callgetTopic(String, Class)— the previous generic<T>overload silently hard-wiredString.classinternally and would corrupt non-String payloads. -
getTopic
-
getSet
Obtain a handle to a distributed set. Same String-serialization caveat asgetMap(String). -
consistencySubsystem
Access the Consistency Subsystem for strongly consistent primitives.The Consistency Subsystem provides Raft-backed, linearizable primitives including linearizable locks, semaphores, and atomic longs. These have stronger consistency guarantees than the eventually-consistent base data structures.
- Returns:
- a Consistency Subsystem factory
- Since:
- 1.4
-
getConsistencySubsystem
JavaBean-style alias forconsistencySubsystem().- Returns:
- a Consistency Subsystem factory
-
sql
Execute a SQL query on the cluster.Returns a result containing the query columns and rows. SQL queries are executed on the cluster and results are returned to the client.
- Parameters:
query- the SQL query string- Returns:
- a SQL result with columns and rows
- Throws:
LoomException- if the query fails or the cluster is unavailable- Since:
- 1.4
-
addIndex
Adds or replaces index metadata for a distributed map through the SQL DDL path.- Parameters:
mapName- the map name to indexconfig- the client-side index configuration- Throws:
LoomException- if the cluster rejects the DDL or is unavailable
-
batch
Create a newLoomBatchfor batching multiple data-structure operations into a single server-side execution.Usage:
// Fast batch (network optimization, no atomicity) client.batch() .map("users").put("user:1", userJson) .counter("visits").increment() .execute(); // Atomic batch (all-or-nothing on this node) client.batch().atomic() .map("accounts").put("acc:1", newBalance) .counter("total").add(delta) .execute(); // Replicated atomic (Raft-committed, crash-safe) client.batch().atomic().replicated() .map("accounts").put("acc:1", newBalance) .counter("total").add(delta) .execute();- Returns:
- a new batch builder
- Since:
- 1.3
-
newTransaction
Begin a new server-side transaction with the default timeout.- Returns:
- a
LoomTransactionfacade for buffering and committing ops - Throws:
LoomException- if the server fails to start the transaction- Since:
- 2.0
- See Also:
-
newTransaction
Begin a new server-side transaction with an explicit timeout.When the timeout elapses before commit or rollback, the server automatically rolls back the transaction and its id becomes invalid.
Usage:
try (LoomTransaction tx = client.newTransaction(Duration.ofSeconds(30))) { tx.put("users", "user:1", "Alice"); tx.setAdd("active-users", "user:1"); tx.commit(); }- Parameters:
timeout- optional timeout; null means use the server default- Returns:
- a
LoomTransactionfacade - Throws:
LoomException- if the server fails to start the transaction- Since:
- 2.0
-
isConnected
public boolean isConnected() -
connectedNodeCount
public int connectedNodeCount() -
connectedNodes
-
isStrictHandshakeEnabled
public boolean isStrictHandshakeEnabled()- Returns:
trueiff the client was built withstrictHandshake(true). Session 7 Sub-mission 2a — accessor is provided ahead of the full ConnectionPool wire-up to give future-session ITs a way to verify the flag propagated without re-exercising the Builder plumbing.- Since:
- 2.1
-
partitionTable
- Returns:
- the client-side partition ownership cache (never null). Populated
lazily — consult
ClientPartitionTable.currentRevision()to detect whether a snapshot has been installed yet. Session 7 Sub-mission 2b — consumers arrive in Session 8 when theRequestRouter.selectNoderewrite lands. - Since:
- 2.1
-
async
Create an async wrapper for this client using CompletableFuture.- Returns:
- a borrowed async facade wrapping this client
-
routingMode
-
routingMemberGroup
-
routingPartitionGroupConfig
-
asyncStart
public boolean asyncStart() -
reconnectMode
-
isReconnecting
public boolean isReconnecting() -
registerCqcListener
public void registerCqcListener(String mapName, LoomClient.MapChangeListener listener, SerializablePredicate predicate) throws LoomException Register a CQC-filtered event listener for the given map. Sends aMessageType.CQC_SUBSCRIBEto every connected node carrying the encodedpredicate; events matching the predicate are pushed back asMessageType.CQC_EVENTand dispatched viahandleListenerEvent(Message).- Parameters:
mapName- source map name (non-blank)listener- the per-event callback (non-null)predicate- the wire-serializable predicate to evaluate server-side- Throws:
LoomException- if no connected node accepts the subscription- Since:
- 2.0
-
deregisterCqcListener
Remove a previously registered CQC listener and deliverMessageType.CQC_UNSUBSCRIBEto every connected node.- Since:
- 2.0
-
registerMapListener
public void registerMapListener(String mapName, LoomClient.MapChangeListener listener) throws LoomException Register a listener for entry events on a specific map. This method now uses resilient retry logic with exponential backoff. If server-push listener registration fails, the client will fall back to TTL-based polling.- Parameters:
mapName- the name of the map to listen tolistener- the listener to register- Throws:
LoomException- if the registration fails
-
registerLocalMapListener
public void registerLocalMapListener(String mapName, LoomClient.MapChangeListener listener) throws LoomException Register an entry listener on exactly one connected member.Unlike
registerMapListener(String, MapChangeListener), this does not fan out the server-side subscription to every node. Events are delivered only when the member that accepted this subscription produces the event.- Parameters:
mapName- the name of the map to listen tolistener- the listener to register- Throws:
LoomException- if no connected member accepts the registration
-
deregisterLocalMapListener
public void deregisterLocalMapListener(String mapName, LoomClient.MapChangeListener listener) throws LoomException Deregister a local-only map listener.- Throws:
LoomException
-
deregisterMapListener
public void deregisterMapListener(String mapName, LoomClient.MapChangeListener listener) throws LoomException Unregister a listener for entry events on a specific map.- Parameters:
mapName- the name of the maplistener- the listener to unregister- Throws:
LoomException- if the deregistration fails
-
evaluatePoolScaling
Monitor and evaluate auto-scaling metrics for a node's connection pool. Returns scaling recommendations that can be used by the ConnectionPool to dynamically adjust pool size based on utilization.This method evaluates whether pool should scale up (sustained high utilization) or down (sustained low utilization) based on configurable thresholds.
- Parameters:
nodeId- the target node IDactiveConnections- current active connectionstotalConnections- total connections in pool- Returns:
- recommended new pool size, or -1 if no scaling is needed
-
builder()instead for better control and clarity