Class CacheNodeConfig

java.lang.Object
com.loomcache.springboot.config.CacheNodeConfig

@Configuration @Conditional(LoomServerEnabledCondition.class) @EnableConfigurationProperties(LoomProperties.class) public class CacheNodeConfig extends Object
Spring Boot configuration for the embedded cache node.

Configurable via application.properties: loomcache.cluster.node-id — unique node identifier loomcache.server.bind-address — bind host loomcache.node.port — bind port loomcache.node.instance — instance number (1, 2, or 3) for log prefix loomcache.cluster.seeds — comma-separated seed list (host:port) — REQUIRED, no default loomcache.cluster.id — cluster UUID (auto-generated if not set)

  • Constructor Details

  • Method Details

    • clusterConfig

      @Bean public ClusterConfig clusterConfig()
      Create cluster configuration bean from properties.
      Returns:
      the cluster configuration
    • cacheNode

      @Bean(destroyMethod="stop") @Conditional(LoomServerEnabledCondition.class) public CacheNode cacheNode(ClusterConfig clusterConfig, org.springframework.beans.factory.ObjectProvider<io.micrometer.core.instrument.MeterRegistry> meterRegistryProvider) throws Exception
      Create and start the cache node bean.

      BLK-2026-04-22-002: the Spring Boot Actuator MeterRegistry (which Spring auto-wires into a Prometheus-backed CompositeMeterRegistry when micrometer-registry-prometheus is on the classpath) is now injected into CacheNode. Previously the single-arg constructor created a throw-away SimpleMeterRegistry, so every loomcache.* metric registered on the cache node never reached /actuator/prometheus. With this wiring, all Raft / WAL / cache metrics are scrapeable.

      Parameters:
      clusterConfig - the cluster configuration
      meterRegistryProvider - provider for the Spring-managed MeterRegistry; resolves to the Prometheus-backed registry when actuator + Prometheus dependency are present, or null otherwise
      Returns:
      the started cache node
      Throws:
      Exception - if startup fails
    • consistentHashRing

      @Bean public ConsistentHashRing consistentHashRing(ClusterConfig clusterConfig)
      Create consistent hash ring bean.
      Returns:
      the consistent hash ring
    • replicationManager

      @Bean @Conditional(LoomServerEnabledCondition.class) public ReplicationManager replicationManager(CacheNode cacheNode, ConsistentHashRing hashRing)
      Create replication manager bean.
      Parameters:
      cacheNode - the cache node
      hashRing - the consistent hash ring
      Returns:
      the replication manager
    • writeThroughCacheStore

      @Bean public WriteThroughCacheStore writeThroughCacheStore(CacheEntryRepository repository)
      Create write-through cache store bean.
      Parameters:
      repository - the cache entry repository
      Returns:
      the write-through cache store
    • defaultMap

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedMap<String,String> defaultMap(CacheNode cacheNode, WriteThroughCacheStore cacheStore)
      Default distributed map with write-through wired up.

      The bean is resolved from

      invalid reference
      CacheNode#getDataStructures()
      so it is the same instance the embedded server uses for cluster routing, replication, and persistence. Creating a standalone new DistributedMap(...) here would give the Spring context a look-alike that is disconnected from the node.

      Warm-up order: the persisted state is loaded and populated into the map BEFORE the write-through/delete-through callbacks are installed. This prevents the prior resurrect-tombstone race — under the old ApplicationReadyEvent warm-up, a live DELETE could remove a key after the DB snapshot was read but before warm-up reached the key, and the subsequent putIfAbsent would silently restore the deleted value. Bean creation is synchronous and happens before the Spring web server accepts traffic, so the HTTP side of the race is eliminated. The residual TCP-side window (CacheNode TCP already accepting as soon as the cacheNode bean is built) is unavoidable without a dedicated readiness gate and is kept narrow by running warm-up synchronously.

      Parameters:
      cacheNode - the embedded cache node whose registry owns the instance
      cacheStore - the write-through cache store
      Returns:
      the distributed map registered under the name "default"
    • defaultQueue

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedQueue<String> defaultQueue(CacheNode cacheNode)
      Create default distributed queue bean, resolved from the node's registry so it shares state with the rest of the embedded server.
      Parameters:
      cacheNode - the embedded cache node
      Returns:
      the distributed queue registered under the name "default"
    • defaultTopic

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedTopic<String> defaultTopic(CacheNode cacheNode)
      Create default distributed topic bean, resolved from the node's registry so it shares state with the rest of the embedded server.
      Parameters:
      cacheNode - the embedded cache node
      Returns:
      the distributed topic registered under the name "default"
    • defaultSet

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedSet<String> defaultSet(CacheNode cacheNode)
      Create default distributed set bean, resolved from the node's registry so it shares state with the rest of the embedded server. Required by SetController; without this bean, application startup fails with NoSuchBeanDefinitionException.
      Parameters:
      cacheNode - the embedded cache node
      Returns:
      the distributed set registered under the name "default"
    • defaultMultiMap

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedMultiMap defaultMultiMap(CacheNode cacheNode)
    • defaultList

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedList<String> defaultList(CacheNode cacheNode)
    • defaultRingbuffer

      @Bean @Conditional(LoomServerEnabledCondition.class) public DistributedRingbuffer<String> defaultRingbuffer(CacheNode cacheNode)
    • defaultReliableTopic

      @Bean @Conditional(LoomServerEnabledCondition.class) public ReliableTopic<String> defaultReliableTopic(CacheNode cacheNode)
    • defaultCounter

      @Bean @Conditional(LoomServerEnabledCondition.class) public PNCounter defaultCounter(CacheNode cacheNode)
    • defaultLock

      @Bean @Conditional(LoomServerEnabledCondition.class) public LinearizableLock defaultLock(CacheNode cacheNode)
    • defaultAtomicLong

      @Bean @Conditional(LoomServerEnabledCondition.class) public LinearizableAtomicLong defaultAtomicLong(CacheNode cacheNode)
    • defaultAtomicReference

      @Bean @Conditional(LoomServerEnabledCondition.class) public LinearizableAtomicReference<String> defaultAtomicReference(CacheNode cacheNode)