阿帕奇 Ignite.NET 和 AppDomain.CurrentDomain.ProcessExit
Apache Ignite.NET and AppDomain.CurrentDomain.ProcessExit
考虑 class,利用 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 创建,当我使用 kill <pid>
.
在 MacOS 上终止控制台应用程序时,AppDomain.CurrentDomain.ProcessExit
将永远不会被触发
我在调试时做了一些研究,发现它会在调用 private static Jvm CreateJvm(IgniteConfiguration cfg, ILogger log)
之后的某个地方发生。
知道那里发生了什么吗,如果有机会我们可以连接到 AppDomain.CurrentDomain.ProcessExit
?
UPD:AppDomain.CurrentDomain.DomainUnload
和 System.Runtime.Loader.AssemblyLoadContext.Unloading
都不起作用。
ProcessExit
is not guaranteed to be called.
我认为Ignite.NET与此无关。我已经检查过这个(没有引用或启动 Ignite),如果你强行终止进程,则不会调用处理程序。
根据Oracle's Java Documentation:
Applications embedding the JVM frequently need to trap signals such as SIGINT or SIGTERM, which can lead to interference with the JVM signal handlers. The -Xrs option is available to address this issue. When -Xrs is used, the signal masks for SIGINT, SIGTERM, SIGHUP, and SIGQUIT are not changed by the JVM, and signal handlers for these signals are not installed.
因此,在稍微修改初始 class 之后,我能够处理 AppDomain.CurrentDomain.ProcessExit
和 Console.CancelKeyPress
// ...
JvmOptions = new List<string>()
{
"-Xrs", // <--------------------
"-DIGNITE_NO_SHUTDOWN_HOOK=true",
},
// ...
考虑 class,利用 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 创建,当我使用 kill <pid>
.
AppDomain.CurrentDomain.ProcessExit
将永远不会被触发
我在调试时做了一些研究,发现它会在调用 private static Jvm CreateJvm(IgniteConfiguration cfg, ILogger log)
之后的某个地方发生。
知道那里发生了什么吗,如果有机会我们可以连接到 AppDomain.CurrentDomain.ProcessExit
?
UPD:AppDomain.CurrentDomain.DomainUnload
和 System.Runtime.Loader.AssemblyLoadContext.Unloading
都不起作用。
ProcessExit
is not guaranteed to be called.
我认为Ignite.NET与此无关。我已经检查过这个(没有引用或启动 Ignite),如果你强行终止进程,则不会调用处理程序。
根据Oracle's Java Documentation:
Applications embedding the JVM frequently need to trap signals such as SIGINT or SIGTERM, which can lead to interference with the JVM signal handlers. The -Xrs option is available to address this issue. When -Xrs is used, the signal masks for SIGINT, SIGTERM, SIGHUP, and SIGQUIT are not changed by the JVM, and signal handlers for these signals are not installed.
因此,在稍微修改初始 class 之后,我能够处理 AppDomain.CurrentDomain.ProcessExit
和 Console.CancelKeyPress
// ...
JvmOptions = new List<string>()
{
"-Xrs", // <--------------------
"-DIGNITE_NO_SHUTDOWN_HOOK=true",
},
// ...