Client API Reference
The LoomCache client SDK provides type-safe access to all 7 distributed data structures. It is thread-safe, supports automatic retry with exponential backoff, features a built-in near cache, and handles leader tracking transparently.
Client SDK Architecture
Smart routing, near cache, pipelining, and auto-retry built in.
Connection Management
Section titled “Connection Management”LoomClient Builder
Section titled “LoomClient Builder”LoomClient client = LoomClient.builder() .addSeed("127.0.0.1:5701") .addSeed("127.0.0.1:5702") .requestTimeout(Duration.ofSeconds(10)) .maxRetries(3) .retryBaseDelay(Duration.ofMillis(100)) .nearCacheEnabled(true) .nearCacheTtlMs(60000) .nearCacheMaxSize(10000) .poolMinSize(5) .poolMaxSize(20) .poolIdleTimeoutMs(300000) .pipelineBatchSize(100) .pipelineFlushTimeoutMs(10) .build();
client.connect();Builder Parameters
Section titled “Builder Parameters”| Category | Method | Default | Description |
|---|---|---|---|
| Connection | addSeed(host:port) | — | Add cluster bootstrap node |
| Timeouts | requestTimeout(Duration) | 10s | Per-request timeout |
| Retry | maxRetries(int) | 3 | Exponential backoff attempts |
| Retry | retryBaseDelay(Duration) | 100ms | Base delay (5s max, ±25% jitter) |
| Near Cache | nearCacheEnabled(boolean) | false | Enable local caching |
| Near Cache | nearCacheTtlMs(long) | 60000 | TTL for cached entries |
| Near Cache | nearCacheMaxSize(int) | 10000 | Max locally cached keys |
| Pool | poolMinSize(int) | 5 | Min connections per node |
| Pool | poolMaxSize(int) | 20 | Max connections per node |
| Pool | poolIdleTimeoutMs(long) | 300000 | Idle connection eviction (5 min) |
| Pipeline | pipelineBatchSize(int) | 100 | Commands per pipeline flush |
| Pipeline | pipelineFlushTimeoutMs(long) | 10 | Max flush delay (ms) |
Client Lifecycle
Section titled “Client Lifecycle”try (LoomClient client = LoomClient.builder() .addSeed("127.0.0.1:5701") .build()) {
client.connect(); boolean connected = client.isConnected(); int nodeCount = client.connectedNodes();
// Use data structures...} // close() called automaticallyAll client classes implement AutoCloseable.
LoomMap<K, V>
Section titled “LoomMap<K, V>”A distributed key-value store with atomic operations, TTL, eviction, and entry listeners.
LoomMap<String, String> map = client.getMap("users");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
mapGet(K) | key | V | null | Get value. Checks near cache first. |
mapPut(K, V) | key, value | V | null | Store entry. Invalidates near cache. Returns previous value. |
mapDelete(K) | key | boolean | Remove entry. Returns true if existed. |
mapContains(K) | key | boolean | Check existence. Uses near cache. |
mapSize() | — | int | Total entries in the map. |
mapKeys() | — | Set<K> | All keys as a set. |
mapValues() | — | Collection<V> | All values. |
mapPutIfAbsent(K, V) | key, value | V | null | Atomic put if absent. Returns existing or null. |
mapReplace(K, V) | key, newValue | V | null | Replace if exists. Returns old value. |
mapClear() | — | void | Remove all entries. |
mapScan(ScanCursor) | cursor | ScanResult | Cursor-based iteration for large maps. |
Entry Listeners
Section titled “Entry Listeners”map.addEntryListener("users", (key, oldValue, newValue) -> { System.out.println("Changed: " + key + " → " + newValue);});Example
Section titled “Example”LoomMap<String, String> users = client.getMap("users");
users.mapPut("user:1", "Alice");users.mapPut("user:2", "Bob");
String name = users.mapGet("user:1"); // "Alice"boolean exists = users.mapContains("user:1"); // trueusers.mapPutIfAbsent("user:3", "Charlie"); // null (inserted)users.mapPutIfAbsent("user:3", "Charlie2"); // "Charlie" (no-op)int total = users.mapSize(); // 3LoomQueue<E>
Section titled “LoomQueue<E>”A distributed FIFO queue. Elements are inserted at the tail and removed from the head.
LoomQueue<String> tasks = client.getQueue("tasks");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
offer(E) | element | boolean | Enqueue at tail. Returns true on success. |
poll() | — | E | null | Dequeue from head. Returns null if empty. |
peek() | — | E | null | View head without removing. |
size() | — | long | Current queue length. |
Example
Section titled “Example”LoomQueue<String> tasks = client.getQueue("tasks");
tasks.offer("process-order-123");tasks.offer("send-email");
String next = tasks.poll(); // "process-order-123"String peek = tasks.peek(); // "send-email"long size = tasks.size(); // 1LoomSet<E>
Section titled “LoomSet<E>”A distributed set ensuring uniqueness.
LoomSet<String> tags = client.getSet("tags");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
add(E) | element | boolean | Add to set. Returns false if exists. |
remove(E) | element | boolean | Remove from set. |
contains(E) | element | boolean | Check membership. |
card() | — | long | Cardinality (size). |
scan(cursor, count) | cursor, count | ScanResult | Cursor-based iteration. |
Example
Section titled “Example”LoomSet<String> tags = client.getSet("tags");
tags.add("java");tags.add("cache");boolean exists = tags.contains("java"); // truetags.remove("cache");long count = tags.card(); // 1LoomSortedSet
Section titled “LoomSortedSet”A scored, ranked collection with O(log N) range queries.
LoomSortedSet leaderboard = client.getSortedSet("leaderboard");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
add(member, score) | member, double | boolean | Add with score. |
remove(member) | member | boolean | Remove member. |
score(member) | member | Double | null | Get score. |
rank(member) | member | Long | null | Rank by ascending score (0-indexed). |
revRank(member) | member | Long | null | Rank by descending score. |
range(start, stop) | long, long | Set<String> | Range by ascending rank. |
revRange(start, stop) | long, long | Set<String> | Range by descending rank. |
incrScore(member, delta) | member, double | double | Increment score atomically. |
card() | — | long | Total members. |
Example
Section titled “Example”LoomSortedSet board = client.getSortedSet("leaderboard");
board.add("alice", 150.0);board.add("bob", 200.0);board.add("charlie", 100.0);
Long rank = board.rank("alice"); // 1 (Charlie=0, Alice=1)Double score = board.score("alice"); // 150.0Set<String> top2 = board.revRange(0, 1); // [Bob, Alice]board.incrScore("alice", 100.0); // Alice now 250.0LoomTopic<T> (Pub/Sub)
Section titled “LoomTopic<T> (Pub/Sub)”Fire-and-forget broadcast messaging to all active subscribers.
LoomTopic<String> events = client.getTopic("events");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
publish(message) | T | void | Broadcast to all subscribers. |
subscribe(id, listener) | subscriberId, Consumer<T> | void | Register message handler. |
unsubscribe(id) | subscriberId | void | Remove handler. |
Example
Section titled “Example”LoomTopic<String> events = client.getTopic("events");
events.subscribe("sub-1", msg -> System.out.println("Received: " + msg));
events.publish("user-login");events.publish("cache-hit");
events.unsubscribe("sub-1");LoomLock (Fenced Distributed Lock)
Section titled “LoomLock (Fenced Distributed Lock)”Distributed lock with monotonically increasing fence tokens for linearizable operations. Safe against split-brain scenarios.
LoomLock lock = client.getLock("critical-section");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
tryLock(clientId, timeout) | String, Duration | long | Acquire lock. Returns fence token (>0) on success, 0 on failure. |
unlock(clientId, fenceToken) | String, long | void | Release lock. Must pass correct fence token. |
Example
Section titled “Example”LoomLock lock = client.getLock("critical-section");
long fenceToken = lock.tryLock("client-1", Duration.ofSeconds(10));if (fenceToken > 0) { try { // Pass fence token to downstream services // for linearizable operation verification } finally { lock.unlock("client-1", fenceToken); }}Fence tokens are monotonically increasing. Downstream services can reject operations with stale fence tokens, preventing split-brain writes.
LoomCounter (Atomic Counter)
Section titled “LoomCounter (Atomic Counter)”CAS-backed atomic counter for rate limiting and sequence generation.
LoomCounter counter = client.getCounter("request-count");Methods
Section titled “Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
incrementAndGet() | — | long | Atomic increment, returns new value. |
get() | — | long | Current value. |
reset() | — | void | Reset to zero. |
increment(n) | long | void | Increment by N. |
Example
Section titled “Example”LoomCounter counter = client.getCounter("request-count");
long val = counter.incrementAndGet(); // 1counter.increment(5); // now 6long current = counter.get(); // 6counter.reset(); // 0Async API
Section titled “Async API”All operations are available asynchronously via AsyncLoomClient:
AsyncLoomClient async = new AsyncLoomClient(syncClient);
CompletableFuture<Void> put = async.mapPut("cache", "key", "value");CompletableFuture<Object> get = async.mapGet("cache", "key");
// Chain operationsasync.mapPut("users", "alice", "Alice Smith") .thenCompose(v -> async.mapGet("users", "alice")) .thenAccept(value -> System.out.println("Got: " + value)) .join();Batch Operations
Section titled “Batch Operations”Execute multiple commands atomically:
LoomBatch batch = client.newBatch();
batch.mapPut("users", "alice", "Alice Smith");batch.mapPut("users", "bob", "Bob Jones");batch.queueOffer("tasks", "process-batch");
batch.execute(); // All-or-nothingPipeline
Section titled “Pipeline”Batch multiple requests in a single round-trip (10–100x latency reduction):
Pipeline pipeline = client.newPipeline();
pipeline.mapPut("cache", "key1", "value1") .mapPut("cache", "key2", "value2") .mapPut("cache", "key3", "value3") .mapGet("cache", "key1");
List<Object> results = pipeline.flush();// results[3] = "value1"CP-by-Default Guarantees
Section titled “CP-by-Default Guarantees”All operations go through Raft consensus:
- Writes are linearizable — leader replicates to majority, persists to WAL
- Linearizable reads — served from leader with valid lease
- Eventual reads — served from followers (stale by ≤100ms)
- During elections — client retries every 100ms for up to 15 seconds
- RESPONSE_REDIRECT — transparent leader re-routing with cached addresses