Apache Ignite.NET и AppDomain.CurrentDomain.ProcessExit - PullRequest
0 голосов
/ 03 сентября 2018

Рассмотрим класс, использующий библиотеку Apache Ignite.NET

public interface ICluster
{
    void Join();

    void Leave();
}

public class ApacheIgniteClusterImpl : ICluster
{
    private IIgnite Ignite { get; set; }

    private int MulticastPort { get; }

    private int ThinClientPort { get; }

    public ApacheIgniteClusterImpl(int multicastPort = 47401, int thinClientPort = 10800)
    {
        MulticastPort = multicastPort;
        ThinClientPort = thinClientPort;
    }

    public void Join()
    {
        if (Ignite != null)
        {
            return;
        }

        var configuration = new IgniteConfiguration
        {
            ClientConnectorConfiguration = new ClientConnectorConfiguration
            {
                Port = ThinClientPort,
            },
            DiscoverySpi = new TcpDiscoverySpi
            {
                IpFinder = new TcpDiscoveryMulticastIpFinder()
                {
                    MulticastPort = MulticastPort,
                }
            },
            JvmOptions = new List<string>()
            {
                "-DIGNITE_NO_SHUTDOWN_HOOK=true",
            },
        };

        // Start
        Ignite = Ignition.Start(configuration);
    }

    public void Leave()
    {
        Ignition.Stop(null, true);
        Ignite = null;
    }
}

Обычно в .NET Standard нам разрешено подключаться к событию AppDomain.CurrentDomain.ProcessExit, где мы могли бы выполнять очистку. Однако после создания JVM в Apache Ignite. NET AppDomain.CurrentDomain.ProcessExit никогда не будет запущен, когда я убиваю консольное приложение на MacOS с kill <pid>.

Я провел некоторое исследование во время отладки и обнаружил, что это произойдет где-то после вызова private static Jvm CreateJvm(IgniteConfiguration cfg, ILogger log).

Есть идеи, что там происходит, и если есть шанс, мы можем подключиться к AppDomain.CurrentDomain.ProcessExit?

UPD : ни AppDomain.CurrentDomain.DomainUnload, ни System.Runtime.Loader.AssemblyLoadContext.Unloading также не будут работать.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Согласно документации Oracle по Java :

Приложениям, внедряющим JVM, часто требуется перехватывать сигналы, такие как SIGINT или SIGTERM, что может привести к помехам в обработчиках сигналов JVM. Опция -Xrs доступна для решения этой проблемы. Когда используется -Xrs, маски сигналов для SIGINT, SIGTERM, SIGHUP и SIGQUIT не изменяются JVM, и обработчики сигналов для этих сигналов не устанавливаются.

Таким образом, после небольшого изменения начального класса я смог обработать AppDomain.CurrentDomain.ProcessExit и Console.CancelKeyPress

// ...
JvmOptions = new List<string>()
{
    "-Xrs", // <--------------------
    "-DIGNITE_NO_SHUTDOWN_HOOK=true",
},
// ...
0 голосов
/ 03 сентября 2018

ProcessExit не гарантированно будет называться .

Я считаю, что Ignite.NET не имеет к этому никакого отношения. Я проверил это (не ссылаясь или не запустив Ignite), и если вы принудительно завершаете процесс, обработчик не вызывается.

...