mirror of https://github.com/jetkvm/kvm.git
fix: signal handling in the native process
This commit is contained in:
parent
f3b854c407
commit
ddce62438c
|
|
@ -82,10 +82,6 @@ func NewGRPCClient(opts grpcClientOptions) (*GRPCClient, error) {
|
||||||
return grpcClient, nil
|
return grpcClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GRPCClient) getContext() context.Context {
|
|
||||||
return c.ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *GRPCClient) handleEventStream(stream pb.NativeService_StreamEventsClient) {
|
func (c *GRPCClient) handleEventStream(stream pb.NativeService_StreamEventsClient) {
|
||||||
c.eventM.Lock()
|
c.eventM.Lock()
|
||||||
c.eventStream = stream
|
c.eventStream = stream
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package native
|
package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -35,23 +36,29 @@ func setProcTitle(status string) {
|
||||||
gspt.SetProcTitle(title)
|
gspt.SetProcTitle(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
func monitorCrashSignal(logger *zerolog.Logger, nativeInstance NativeInterface) {
|
func monitorCrashSignal(ctx context.Context, logger *zerolog.Logger, nativeInstance NativeInterface) {
|
||||||
logger.Info().Msg("DEBUG mode: will crash the process on SIGHUP signal")
|
logger.Info().Msg("DEBUG mode: will crash the process on SIGHUP signal")
|
||||||
|
|
||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigChan, syscall.SIGHUP)
|
signal.Notify(sigChan, syscall.SIGHUP)
|
||||||
|
|
||||||
// non-blocking receive
|
for {
|
||||||
select {
|
select {
|
||||||
case <-sigChan:
|
case sig := <-sigChan:
|
||||||
logger.Info().Msg("received SIGHUP signal, emulating crash")
|
logger.Info().Str("signal", sig.String()).Msg("received termination signal")
|
||||||
nativeInstance.DoNotUseThisIsForCrashTestingOnly()
|
nativeInstance.DoNotUseThisIsForCrashTestingOnly()
|
||||||
default:
|
case <-ctx.Done():
|
||||||
|
logger.Info().Msg("context done, stopping monitor process")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunNativeProcess runs the native process mode
|
// RunNativeProcess runs the native process mode
|
||||||
func RunNativeProcess(binaryName string) {
|
func RunNativeProcess(binaryName string) {
|
||||||
|
appCtx, appCtxCancel := context.WithCancel(context.Background())
|
||||||
|
defer appCtxCancel()
|
||||||
|
|
||||||
logger := nativeLogger.With().Int("pid", os.Getpid()).Logger()
|
logger := nativeLogger.With().Int("pid", os.Getpid()).Logger()
|
||||||
setProcTitle("starting")
|
setProcTitle("starting")
|
||||||
|
|
||||||
|
|
@ -98,6 +105,11 @@ func RunNativeProcess(binaryName string) {
|
||||||
}
|
}
|
||||||
setProcTitle("ready")
|
setProcTitle("ready")
|
||||||
|
|
||||||
|
if _, err := os.Stat(DebugModeFile); err == nil {
|
||||||
|
logger.Info().Msg("DEBUG mode: enabled")
|
||||||
|
go monitorCrashSignal(appCtx, &logger, nativeInstance)
|
||||||
|
}
|
||||||
|
|
||||||
// Signal that we're ready by writing handshake message to stdout (for parent to read)
|
// Signal that we're ready by writing handshake message to stdout (for parent to read)
|
||||||
// Stdout.Write is used to avoid buffering the message
|
// Stdout.Write is used to avoid buffering the message
|
||||||
_, err = os.Stdout.Write([]byte(proxyOptions.HandshakeMessage + "\n"))
|
_, err = os.Stdout.Write([]byte(proxyOptions.HandshakeMessage + "\n"))
|
||||||
|
|
@ -105,11 +117,6 @@ func RunNativeProcess(binaryName string) {
|
||||||
logger.Fatal().Err(err).Msg("failed to write handshake message to stdout")
|
logger.Fatal().Err(err).Msg("failed to write handshake message to stdout")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(DebugModeFile); err == nil {
|
|
||||||
logger.Info().Msg("DEBUG mode: enabled")
|
|
||||||
go monitorCrashSignal(&logger, nativeInstance)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up signal handling
|
// Set up signal handling
|
||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
|
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
|
||||||
|
|
@ -120,8 +127,10 @@ func RunNativeProcess(binaryName string) {
|
||||||
Str("signal", sig.String()).
|
Str("signal", sig.String()).
|
||||||
Msg("received termination signal")
|
Msg("received termination signal")
|
||||||
|
|
||||||
// Graceful shutdown
|
// Graceful shutdown might stuck forever,
|
||||||
server.GracefulStop()
|
// we will use Stop() instead to force quit the gRPC server,
|
||||||
|
// we can implement a graceful shutdown with a timeout in the future if needed
|
||||||
|
server.Stop()
|
||||||
lis.Close()
|
lis.Close()
|
||||||
|
|
||||||
logger.Info().Msg("native process exiting")
|
logger.Info().Msg("native process exiting")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue