Search code examples
javaspringignite

Ignite Server Node with CacheJdbcPojoStore / Delay Client Node


I'm using Spring and Ignite Spring to run a pretty simple cluster consisting of one server node and multiple client nodes with varying domain logic.

Ignite configuration:

  • All nodes connect via TcpCommuncationSpi, TcpDiscoverySpi and TcpDiscoveryVmIpFinder. TcpDiscoveryVmIpFinder.setAddresses only contain the server node.
  • The server node has serveral CacheJdbcPojoStore configured, the database data is loaded after calling Ignition.start(cfg) using ignite.cache("mycachename").loadCache(null).

After a client node is connected to the server node, it does some domain specific checks to verify data integrity. This works very well if I first start the server node, wait for all data to be loaded and then start the client nodes.

My problem: if I first start the client nodes, they can't connect to the server node as it is not yet started. They patiently wait for the server node to come up. If I now start the server node, the client nodes connect directly after Ignition.start(cfg) is done on the server node, but BEFORE the CacheJdbcPojoStores are done loading their data. Thus the domain specific integrity checks do fail as there is no data present in the caches yet.

My goal: I need a way to ensure the client nodes are only able to connect to the server node AFTER all data is loaded in the server node. This would simply the deployment process as well as local development a lot, as there would be no strict ordering of starting the nodes.

What I tried so far: Fiddling around with ignite.cluster().state(ClusterState.INACTIVE) as well as setting up a manually controlled BaselineTopology. Sadly, both methods simple declare the cluster as not being ready yet and thus I can't even create the caches, let alone load data.

My question: Is there any way to achieve either:

  1. hook up into the the startup process of the server node so I can load the data in BEFORE it joins the cluster
  2. Declare the server node "not yet ready" until the data is loaded.

Solution

  • Use one of the available data structures like AtomicLong or Semaphore to simulate readiness state. There is no need for internal hooks.

    Added an example below:

    Client:

    while (true) {
        // try get "myAtomic" and check its value
        IgniteAtomicLong atomicLong = ignite.atomicLong("myAtomic", 0, false);
        if (atomicLong != null && atomicLong.get() == 1) {
            
            // initialization is complete
            break;
        }
    
        // not ready
        Thread.sleep(1000);
    }
    

    Server:

    ...
    
    //loading is complete, create atomic sequence and set its value to 1
    ignite.atomicLong("myAtomic", 1, true);
    ...
    

    UPDATE#2

    instead of having a self-written-loop including Thread.sleep, latch.await() can be called. See: countdownlatch