You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JDK 17 Downgrade — Minimum Java version lowered from 25 to 17. Replaced JDK 21+ APIs (Thread.startVirtualThread(), unnamed _ lambda parameters) with JDK 17-compatible equivalents.
Version Bump — All POMs, READMEs, and metadata updated to 1.1.4.
Consistent Hash Ring (ADR 0005, 0006, 0007)
Consistent Hash Ring — New sharding layer using Guava murmur3_32_fixed() with TreeMap + virtual nodes (default 500/node). Lock-free reads via volatile ring snapshot. Collision probability <3% with 500 vnodes × 100 Workers.
RingManager — Orchestrates ring with auto (heartbeat-discovered) and manual (operator override) modes. Heartbeat timeout: 5s default.
WorkerHealthMonitor Eliminated — Replaced by RingManager. Node identity migrated from int shardIndex to String nodeId across all modules (WorkerMessage, report queues, heartbeats).
Key-Based Worker Routing — routeNode(key) maps cache keys to responsible Worker nodes via consistent hash ring with liveness predicate.
Decentralized Config Gossip (ADR 0003)
Decentralized Config Gossip — WorkerConfigNegotiator listens for heartbeat-borne state-machine config from peers. Applies when remote timestamp > local. Falls back to WorkerProperties defaults if no heartbeat within 3s.
Heartbeat Enriched with Config — broadcastHeartbeat() now carries confirmCount, coolCount, preCoolGraceCount, and monotonic configTimestamp in AMQP headers. No dedicated config store needed.
configTimestampCounter — Shared AtomicLong for config-change ordering across the Worker cluster.
Graceful Degradation (ADR 0001, 0009)
Local Promotion with Worker-Aware Fallback — promoteLocalHotkeyIfNeeded() upgrades NORMAL always; COOL only when all Workers dead. Local TopK takes over during Worker outage; self-heals via decisionVersion on Worker recovery.
Graceful Degradation Path — When isAnyWorkerAlive() == false: COOL entries become promotable, Reporter drops batches silently, Worker recovery auto-reasserts authority.
Null-Safe evaluateRule() — Returns ALLOW instead of throwing when hotKeyCache is null (Worker-only mode).
Dual Version Space (ADR 0008)
Two-Version Architecture — dataVersion (Redis INCR, may degrade to node-local counter) for cross-instance sync; decisionVersion (Worker AtomicLong, never degrades) for HOT/COOL ordering. Orthogonal.
VersionGuard Refactored — Overloaded methods accepting CacheEntry directly for use inside compute() blocks, eliminating redundant getIfPresent calls.
Degraded Comparison — 4-case comparison prevents degraded dataVersion from overwriting normal ones across instances.
Performance & Concurrency
Atomic Cache Operations — All writes use caffeineCache.asMap().compute() instead of blind put(). Worker-managed entries (HOT/COOL) preserved via isWorkerManagedEntry() guard.
SingleFlight Exception-Only Invalidate (ADR 0002) — Removed whenComplete invalidate; only catch-block invalidates. Normal completions stay cached via Caffeine expireAfterWrite.
Batch Invalidation Chunking — Large key sets split into 1000-key AMQP messages to prevent oversized message rejection.
SpEL Expression Caching — Parsed Expression objects cached in ConcurrentHashMap across invocations.
Fallback Method Caching — Resolved methods cached in ConcurrentHashMap to avoid repeated reflection.
CacheExpireManager Jitter — Hard/soft expire timestamps apply ±10% jitter via ThreadLocalRandom to prevent thundering herd.
RingEndpoint — /actuator/hotkeyring with full CRUD (GET, POST addNode, DELETE removeNode, POST rebuild).
StateMachineEndpoint — /actuator/hotkey/worker/state with GET (config) and POST (update confirmCount/coolCount/preCoolGraceCount). Changes propagate via heartbeat gossip.
Expanded Public API
getLocalCache() — Exposes raw Caffeine Cache for introspection.
notifyLocalDetector() — Feeds local TopK without Worker report.
isWorkerHotKey() — O(K) list iteration → O(1) contains().
Configuration Changes
confirm-duration-ms Default — 2000 → 300. HOT promotion within 300ms (was 2s).
evict-interval-ms — New (default 30000) for dedicated eviction.
shard-count / shard-index Removed — Replaced by auto-generated nodeId.
Consistent Hashing Properties — New enabled (default true) and virtual-nodes (default 500).