Search code examples
.netignite

Ignite node hangs when having IService as cluster singleton with persistence enabled


I fail to create sample of a cluster singleton IService with enabled persistency. I attempt to run the following c# code on a Win 10 computer with ignite version 2.4. Starting the application once works and produces the following output (as expected):

  • Nodes = 1
  • Deployed =
  • Service init
  • Service Execute
  • Service is deployed..

Starting the same application a second time makes it hang at 'services.DeployClusterSingleton'. The output is:

  • Nodes = 2
  • Deployed =

Changing 'PersistenceEnabled' to false, makes both (even more than two) applications run as expected.

I do not need persistency for the service itself, but for caches (not part of the sample code). I did not find a way to configure for a service whether or not to use persistency.

[Serializable]
public class CounterService : IService
{
    public void Init(IServiceContext context)
    {
        Console.WriteLine("Service Init");
    }

    public void Execute(IServiceContext context)
    {
        Console.WriteLine("Service Execute");
    }

    public void Cancel(IServiceContext context)
    {
        Console.WriteLine("Service Cancel");
    }
}

static void Main(string[] args)
{
    var config = new IgniteConfiguration()
    {
        DataStorageConfiguration = new DataStorageConfiguration()
        {
            DefaultDataRegionConfiguration = new DataRegionConfiguration()
            {
                Name = "PersistentDefaultRegion",
                PersistenceEnabled = true,
            },
        },
    };

    using (var ignite = Ignition.Start(config))
    {
        ignite.GetCluster().SetActive(true);
        Console.WriteLine("Nodes = " + ignite.GetCluster().GetNodes().Count);

        var services = ignite.GetServices();
        var deployed = services.GetServiceDescriptors().Select(m => ", " + m.Name).ToArray();
        Console.WriteLine("Deployed = " + string.Join("\n", deployed));

        services.DeployClusterSingleton("test-service", new CounterService());
        Console.WriteLine("Service is deployed..");

        Console.ReadLine();
    }
}

Solution

  • It is the known issue: https://issues.apache.org/jira/browse/IGNITE-8134.

    If a node is not a part of the baseline topology, the services will never be deployed on it. In particular, if that node calls synchronous deploy method, the method will hang.

    The preferable way is:

    • start all server nodes
    • setup baseline topology
    • activate cluster
    • deploy services

    Also, you can use Cluster Activation Tool https://apacheignite.readme.io/docs/cluster-activation#section-cluster-activation-tool.

    In your case, it is also possible to add a node to the topology before deploying service using the following code:

    var baselineTopology = ignite.GetCluster().GetBaselineTopology();
    var localNode = ignite.GetCluster().GetLocalNode();
    
    if (baselineTopology.Count(n => n.ConsistentId.ToString() == localNode.ConsistentId.ToString()) == 0)
    {
        baselineTopology.Add(localNode);
        ignite.GetCluster().SetBaselineTopology(baselineTopology);
    }
    

    Just make sure that there is no race condition in updating Baseline Topology and nodes start one by one.