Client API Reference
Client SDK Architecture
Smart routing, near cache, pipelining, and auto-retry built in.
The client SDK lives in loom-client and targets Java 17+. The root class is LoomClient; async variants come from
AsyncLoomClient.
The published Java API documentation is generated from the Maven aggregate Javadoc target and deployed with this docs site at /api/javadoc/. Build it locally with:
mvn -q -DskipTests -DskipITs -DskipIntegrationTests javadoc:aggregateConstruction
Section titled “Construction”LoomClient client = LoomClient.builder() .addSeed("127.0.0.1:5701") .addSeed("127.0.0.1:5702") .addSeed("127.0.0.1:5703") .connectionTimeout(Duration.ofSeconds(5)) .requestTimeout(Duration.ofSeconds(15)) .maxRetries(3) .retryBaseDelay(Duration.ofMillis(100)) .tlsConfig(TlsConfig.disabled()) .auth("alice", "admin,operator") // optional — forwarded on AUTH handshake .nearCacheEnabled(true) .nearCacheTtl(Duration.ofSeconds(30)) .nearCacheMaxSize(10_000) .build();
client.connect();Every builder method exists on LoomClient.Builder — any property not listed above is not currently supported.
LoomMap<K, V> — client.getMap(name)
Section titled “LoomMap<K, V> — client.getMap(name)”LoomMap<K,V> generics are a Java client convenience, not Hazelcast-style implicit object mode. In this release,
arbitrary POJO map values are not production-supported; use the documented scalar and binary value encodings until the
public map path is certified through client round-trip, Raft apply, WAL replay, snapshot restore, and restart tests.
| Category | Methods |
|---|---|
| Read | get(K), containsKey(K), size(), getAll(Collection<K>) |
| Write | put(K, V), putIfAbsent(K, V), putAll(Map), delete(K), getAndRemove(K) |
| Atomic | computeIfAbsent(K, Function<K, V>) |
| Iterate | scan(cursor), scan(cursor, pattern), scan(cursor, pattern, count); scanner(), scanner(pattern), scanner(pattern, pageSize) |
| Per-call | get(K, Duration), put(K, V, Duration), delete(K, Duration), containsKey(K, Duration) |
| Async | getAsync, putAsync, deleteAsync, containsKeyAsync, sizeAsync |
| Stats | getStats() → LoomMapStats(hits, misses, requests, errors, hitRatePercent) |
LoomQueue<E> — client.getQueue(name)
Section titled “LoomQueue<E> — client.getQueue(name)”offer(E),poll(),peek(), plusofferAsync,pollAsync,peekAsync.
LoomSet<E> — client.getSet(name)
Section titled “LoomSet<E> — client.getSet(name)”add,remove,contains,size,clear,scan/scanner, and async variants.
LoomTopic<T> — client.getTopic(name) / client.getTopic(name, Class<T>)
Section titled “LoomTopic<T> — client.getTopic(name) / client.getTopic(name, Class<T>)”publish(T),subscribe(Consumer<T>)→ subscription id,unsubscribe(id),closeSubscriptions(),activeSubscriptionCount().- Failure counters:
getDecodeFailureCount(),getListenerFailureCount().
CP primitives — client.consistencySubsystem()
Section titled “CP primitives — client.consistencySubsystem()”LoomConsistencySubsystem cp = client.consistencySubsystem();LoomAtomicLong counter = cp.getAtomicLong("hits");counter.incrementAndGet();counter.compareAndSet(10, 20);
LoomLinearizableLock lock = cp.getLock("resource"); // wire path fails closed in productionLoomAtomicLong— fully Raft-replicated viaCP_ATOMIC_*.LoomLinearizableLock— API ships client-side, but the server currently rejectsCP_LOCK_*with an unsupported-operation response.CP_SEMAPHORE_*is in the same unsupported/fail-closed production class until session create/heartbeat/close/expiry/force-close opcodes exist and recover through Raft. Use the embeddedConsistencySubsystemonly for non-production embedded scenarios.
Batch operations — client.batch()
Section titled “Batch operations — client.batch()”client.batch() .mapPut("users", "alice", "Alice") .mapPut("users", "bob", "Bob") .mapDelete("users", "eve") .execute();A single BATCH_EXECUTE request runs atomically under the server’s mutation lock.
Run SQL against a named map and receive a LoomSqlResult:
// User must have an explicit supported serializer/encoding before production use.LoomMap<String, User> users = client.getMap("users");LoomSqlResult result = users.query("SELECT key, name, age FROM users WHERE age > 30");See SQL engine for supported syntax. CREATE INDEX and declarative SQL indexes are
unsupported/rejected in this release; full-scan fallback is not Hazelcast index parity.
Async facade
Section titled “Async facade”AsyncLoomClient returns CompletableFutures for the same operations. Use it when you need non-blocking composition.
Local caches
Section titled “Local caches”Under com.loomcache.client.cache:
NearCache— sized LRU with TTL, updated by server-push invalidations.ReadThroughCache,AsyncReadThroughCache— cache-loader fronted with single-flight coalescing.WriteBehindCache— in-process buffer with asynchronous flush to the cluster.CacheLoader,AsyncCacheLoader— SPIs you implement.
Retry & routing
Section titled “Retry & routing”RetryPolicy— exponential backoff with jitter, retries only retryable exceptions.RequestRouter— partition-aware, collision retry, leader fallback.LeaderTracker— caches the last known leader; cleared explicitly or on authenticated redirect.ClientRequestDeduplicator— stamps mutating requests with<clientId, sequence>for server-side dedupe of retries.
Wire protocol reminder
Section titled “Wire protocol reminder”- 16-byte header:
magic | opcode | correlationId | bodyLen | flags | keyLen | status | reserved. - 108 opcodes in
MessageType.java. - Response opcodes:
RESPONSE_OK,RESPONSE_ERROR,RESPONSE_NOT_FOUND,RESPONSE_REDIRECT,RESPONSE_SERVER_BUSY,RESPONSE_SEQUENCE_LOST.