Skip to content

System Architecture & Design

This page describes the LoomCache system architecture: the module layout, the write and read paths, and the responsibilities of each subsystem.

LoomCache consists of six Maven modules with a strict dependency chain. Every node runs one TCP server and at least one Raft state machine (raft-0 by default); opt-in sharding starts multiple Raft groups and routes operations to the owning group. Production deployments must keep sharding disabled until every group has independent WAL, Raft metadata, snapshot, install-snapshot, and restart recovery evidence. The production profile is expected to fail closed otherwise. The client SDK learns leaders and partition ownership through redirects and table refreshes, and caches them for partition-aware routing.

LoomCache Architecture Stack

Waiting for client request...

LoomClientkey hash
Network Layer
Protocol & Auth
Raft Leader
Raft Log
Follower 1
Follower 2
WAL
State & Storagefsync WAL + Map/Queue/Topic
Stageawaiting request
  • loom-common (Java 17+): shared protocol contracts, Kryo serialization, ClusterConfig, TlsConfig, AuthConfig, model DTOs, and exceptions.
  • loom-server (Java 25, --enable-preview): TCP server, Raft, data structures, WAL, snapshots, and the CP subsystem.
  • loom-client (Java 17+): smart routing, connection lifecycle management, near cache, retry, request deduplication, and CP facades.
  • loom-cli (Java 17+): data-structure inspection, cluster state, Raft log export, and CP admin commands.
  • loom-spring-boot: Spring Boot 4.1.0 auto-configuration, REST controllers, and cache/session beans.
  • loom-integration-tests: multi-node integration-test suite with a Java Chaos-style harness.
  1. The client hashes the key, picks a likely partition owner, and sends a map write request.
  2. The TCP listener accepts the connection on a virtual thread and dispatches the request.
  3. Followers respond with the current leader’s address; the client caches that leader and retries there.
  4. The leader wraps the message as a Raft log entry, appends it, and replicates it through AppendEntries.
  5. Once a majority acknowledges, the state-machine applier decodes and runs the command through the data-operation handler and returns the response message.
  6. The client response is released after the committed entry is applied. Persistent Raft logs and WAL/snapshot components provide the disk durability path.
  • Linearizable reads use ReadIndex: the leader captures its commit index at receive time and, while its lease is valid, answers with no disk I/O and no quorum round-trip. An expiring lease triggers one lease-confirmation round first.
  • Linearizable reads on followers return a redirect response — everything routes to the leader.
  • CP atomic-long reads take the same ReadIndex path through the consistency subsystem.

The Raft implementation is part of the server module:

  • Node state machine — LEARNER → FOLLOWER → CANDIDATE → LEADER; LEARNER is a non-voting join state. The implementation uses pre-vote, randomized election timeouts, and a leader lease.
  • Log index — in-memory Raft indexing; durable command records are appended through the write-ahead log.
  • Leader lease tracking — lets the leader answer linearizable reads without a quorum round trip while the lease is valid.
  • Runtime invariant checks exercise Raft safety properties during validation.
  • Membership changes — single-server, learner-first changes (joint consensus is intentionally not used; an unsafe arbitrary-reconfiguration path is disabled, and the production profile rejects it).

Default deployments run a single Raft group over the full cluster. When ClusterConfig.shardingEnabled(true) is set, the node starts multiple groups and dispatches Raft RPCs by group name. That multi-group path is a development/validation surface, not production support, until per-group recovery is proven end to end with durable migration chunk ACKs, consensus-backed ownership cutover, and an explicit sharding release gate.

  • Write-ahead log persistence uses a single append-only file per node, with per-record integrity checks, torn-tail recovery by record scan on boot, and configurable durability (FSYNC per Raft commit; WRITE, NONE, and deferred-fsync batching are rejected for committed Raft WALs).
  • Snapshots are full point-in-time images, and registered data structures contribute their state to each one. Automatic compaction creates a full snapshot and then compacts the WAL entries that snapshot already covers.
  • Raft metadata persists the current term, vote, and commit index.
  • Setting dataDir = null disables persistence for tests and non-production experiments only; production startup requires durable Raft WAL storage.
  • Failure detection uses a phi-accrual detector; membership state is Raft-driven.
  • Discovery uses direct-connect static seed lists.
  • Consistent hashing and membership-slot tables feed smart client routing.
  • Production CP support covers atomic long, lock, and Java-client-managed semaphore calls. Java client lock/semaphore calls create and heartbeat the Raft-managed CP session internally; sessionless semaphore mutations fail closed. Atomic-reference and latch handles are not production-supported; production profiles reject their direct requests.
  • Embedded CP primitives can be used in-process for non-production or controlled embedded scenarios, but they are not a substitute for a supported session lifecycle.
  • Executor task submission is production-enabled only through the deny-all-default task allowlist (loomcache.executor.allowlist). Keep production executor workloads to explicitly approved task classes with release-specific recovery evidence.
  • EntryProcessor execution is production-enabled only through the deny-all-default processor allowlist (loomcache.entryprocessor.allowlist). Kryo registration alone is serialization compatibility, not code-execution authorization.
  • One virtual thread per TCP connection in the binary listener.
  • A virtual-thread command executor dispatches commands.
  • Raft replication, WAL fsync, snapshot scheduling, and partition migration run on dedicated ScheduledExecutorServices — not virtual threads — so the fan-out stays bounded.

LoomCache is an independent open-source project. It is not affiliated with, endorsed by, or sponsored by Hazelcast, Inc. or by any other company whose products are named in this documentation. “Hazelcast” is a trademark of Hazelcast, Inc.; references to it are nominative and describe only migration and comparison. All other product and company names are trademarks of their respective owners and are used for identification purposes only.