0

Here is a simple Ignite cluster (in C#) with one server node and one client node. The server adds entries to a single cache and the client listens for those entries.

Server:

    class Program
    {
      static void Main(string[] args)
      {
        var ignite = Ignition.Start();
        var cache = ignite.GetOrCreateCache<long, string>("my-cache");
            
        var key = 1L;
        while (true)
        {
          cache.Put(key, $"Hello, {key}");
          Console.WriteLine(cache.Get(key));
    
          Thread.Sleep(TimeSpan.FromSeconds(1));
          key += 1;
        }
      }
    }

Client:

    class Program
    {
        static void Main(string[] args)
        {
            var cfg = new IgniteConfiguration { ClientMode = true };
            var ignite = Ignition.Start(cfg);
            var cache = ignite.GetCache<long, string>("my-cache");

            var qry = new ContinuousQuery<long, string>(new CacheListener(), null);
            using (cache.QueryContinuous(qry))
            {
                while (true)
                    Thread.Sleep(TimeSpan.FromSeconds(1));
            }
        }
    }

    class CacheListener : ICacheEntryEventListener<long, string>
    {
        public void OnEvent(IEnumerable<ICacheEntryEvent<long, string>> evts)
        {
            foreach(var e in evts)
                Console.WriteLine(e.Value);
        }
    }

Issue #1: The client works as expected when it first joins the cluster. But if I restart just the server node, the client node doesn't receive any continuous query notifications after re-joining the cluster.

Why doesn't the continuous query restart when the client node rejoins the cluster? Are there additional steps I should take to restart the continuous query?

Issue #2: I attempted to LocalListen() for EventType.ClientNodeReconnected with the plan of restarting the query by force. However Ignite is in an unusable state at that point.

    class ClientNodeListener : IEventListener<DiscoveryEvent>
    {
        public bool Invoke(DiscoveryEvent evt)
        {
            if (evt.Type == EventType.ClientNodeReconnected)
                Program.StartContinuousQuery();

            return true;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var cfg = new IgniteConfiguration
            {
                ClientMode = true,
                IncludedEventTypes = new[] { EventType.ClientNodeReconnected }
            };

            var ignite = Ignition.Start(cfg);
            ignite.GetEvents().LocalListen(new ClientNodeListener(), EventType.ClientNodeReconnected);

            StartContinuousQuery();
            while (true)
                Thread.Sleep(TimeSpan.FromSeconds(1));
        }

        public static void StartContinuousQuery()
        {
            var ignite = Ignition.GetIgnite();

            // After rejoining the cluster, this line will timeout 
            // with 'Blocked system-critical thread has been detected' errors in the log 
            var cache = ignite.GetCache<long, string>("my-cache");

            var qry = new ContinuousQuery<long, string>(new CacheListener(), null);
            qry.AutoUnsubscribe = true;

            cache.QueryContinuous(qry);
        }
    }

1 Answers1

0

There is only one server node. Restarting the only server means that the entire cluster is restarted. In this case you have to start a new continuous query by subscribing to ClientReconnected event:

client.ClientReconnected += (sender, eventArgs) =>
{
    if (eventArgs.HasClusterRestarted)
    {
        StartContinuousQuery();
    }
};

If the cluster does not go down (some servers may stop, but at least one node remains online), the continuous query will remain active.

Pavel Tupitsyn
  • 8,393
  • 3
  • 22
  • 44