我在Go程序上遇到了麻烦,该程序本应捕获SIGTERM并正常关闭。我可以看到它启动了关闭过程,但是随后突然退出而没有完成关闭过程。我在不同的地方放置了一些日志,可以看到他们没有在stdout上打印任何内容。这是一个代码段和结果:

    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)

    select {
    case <-sigs:
        signal.Stop(sigs)
        log.Info().Msg("runsomething: SIGTERM caught")
        close(stopC)
        cancel()
        log.Info().Msg("Stopping all goroutines")

        // This sleep doesn't have any effect when shutdown via SIGTERM
        time.Sleep(time.Second * 2)
        log.Info().Msg("THIS SHOULD PRINT, WHY DOESNT IT?")
    case <-doneC:
    }

    // This sleep doesn't have any effect when shutdown via SIGTERM nor
    // does the following log print
    time.Sleep(time.Second * 2)
    log.Info().Msg("runsomething: DONE")


这是正常完成的结果:
./runsomething
May  5 09:46:35.000 INF runsomething started
May  5 09:46:37.000 INF Summarizing results and exiting
May  5 09:46:37.000 INF Run results COMPLETED
May  5 09:46:39.000INF runsomething: DONE

这是带有中断的结果:
May  5 09:39:48.000 INF runsomething started
^CMay  5 09:39:50.000 INF runsomething: SIGTERM caught
May  5 09:39:50.000 INF Stopping all goroutines
May  5 09:39:50.000 INF GracefulShutdown: Started

缺少几条输出线。鉴于以上代码段,我希望看到:
...continued from above...
May  5 09:39:50.000 INF THIS SHOULD PRINT, WHY DOESNT IT? The sleep below also isn't run?
May  5 09:39:50.000 INF GracefulShutdown: Completed
May  5 09:39:50.000 INF runsomething: DONE
time.Sleep()调用似乎无效。在初始日志中声明了GracefulShutdown: Started之后,程序无提示退出之前没有暂停。我尝试用一​​个更小的示例来重现该问题,该示例模仿上面的代码,但它按预期工作。我将不胜感激,可以尝试任何想法或其他故障排除步骤。

编辑:
最后执行的语句是调试日志记录语句。当我注释掉其后的fmt.Printf时,程序将按预期工作。注意:它正在打印与上面的log语句相同的[]byte
    rsjson, err := json.Marshal(runSummary)
    if err != nil {
        log.Error().Err(err).Msgf("error marshaling RunSummary into string: %+v.\n")
        return
    }

    // TODO: debug stuff, only the printf should remain
    log.Info().Msgf("Run results: \n\n%s\n", rsjson)
    // TODO Removed Printf to see if it makes a difference
    // fmt.Printf("%s\n", string(rsjson))
    log.Info().Msgf("Run results COMPLETED")

最佳答案

我知道我做错了。事实证明代码正在运行。虽然我使用的命令与我在原始问题中输入的命令不完全相同。如果我按照上面最初发布的命令运行命令:

./runsomething

它在被中断时可以正常工作(^C)。

但是,实际的命令将输出如下所示:
./runsomething | jq .

这表现出上述行为,未打印输出。让我感到困惑的是,日志记录将进入stderr,因此,除了最后一个fmt.Printf之外,一切似乎都在工作。再考虑一下,我取消了整个管道,即runsomethingjq,而不仅仅是runsomething。 h!

关于go - Golang信号处理和time.Sleep()交互,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61617844/

10-11 23:08
查看更多