From e9e1b66274186d047be87beeebe57fd66d627368 Mon Sep 17 00:00:00 2001 From: Angelo Capossele <angelocapossele@gmail.com> Date: Mon, 29 Jun 2020 13:59:31 +0100 Subject: [PATCH] Make WaitToKillTimeInSeconds a parameter (#570) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✅ Make WaitToKillTimeInSeconds a parameter * 🔧 Set default ParaWaitToKill to 60 seconds * 🛠Fix bug --- pluginmgr/core/plugins.go | 2 +- plugins/gracefulshutdown/parameters.go | 14 ++++ plugins/gracefulshutdown/plugin.go | 84 ++++++++++--------- .../tester/framework/docker.go | 1 + .../tester/framework/parameters.go | 2 + .../consensus/consensus_conflicts_test.go | 3 + 6 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 plugins/gracefulshutdown/parameters.go diff --git a/pluginmgr/core/plugins.go b/pluginmgr/core/plugins.go index d604ddf2..03191820 100644 --- a/pluginmgr/core/plugins.go +++ b/pluginmgr/core/plugins.go @@ -29,6 +29,7 @@ var PLUGINS = node.Plugins( config.Plugin(), logger.Plugin(), cli.Plugin(), + gracefulshutdown.Plugin(), portcheck.Plugin(), profiling.Plugin(), database.Plugin(), @@ -39,7 +40,6 @@ var PLUGINS = node.Plugins( issuer.Plugin(), bootstrap.Plugin(), sync.Plugin(), - gracefulshutdown.Plugin(), metrics.Plugin(), drng.Plugin(), faucet.App(), diff --git a/plugins/gracefulshutdown/parameters.go b/plugins/gracefulshutdown/parameters.go new file mode 100644 index 00000000..fbdca5fe --- /dev/null +++ b/plugins/gracefulshutdown/parameters.go @@ -0,0 +1,14 @@ +package gracefulshutdown + +import ( + flag "github.com/spf13/pflag" +) + +const ( + // CfgWaitToKillTimeInSeconds the maximum amount of time to wait for background processes to terminate. + CfgWaitToKillTimeInSeconds = "gracefulshutdown.waitToKillTime" +) + +func init() { + flag.Int(CfgWaitToKillTimeInSeconds, 60, "the maximum amount of time to wait for background processes to terminate, in seconds") +} diff --git a/plugins/gracefulshutdown/plugin.go b/plugins/gracefulshutdown/plugin.go index efc50f74..b191f7e3 100644 --- a/plugins/gracefulshutdown/plugin.go +++ b/plugins/gracefulshutdown/plugin.go @@ -9,6 +9,7 @@ import ( "syscall" "time" + "github.com/iotaledger/goshimmer/plugins/config" "github.com/iotaledger/hive.go/daemon" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" @@ -17,59 +18,60 @@ import ( // PluginName is the name of the graceful shutdown plugin. const PluginName = "Graceful Shutdown" -// WaitToKillTimeInSeconds is the maximum amount of time to wait for background processes to terminate. -// After that the process is killed. -const WaitToKillTimeInSeconds = 60 - var ( // plugin is the plugin instance of the graceful shutdown plugin. - plugin *node.Plugin - once sync.Once - log *logger.Logger - gracefulStop chan os.Signal + plugin *node.Plugin + once sync.Once + log *logger.Logger + gracefulStop chan os.Signal + waitToKillTimeInSeconds int ) -// Plugin gets the plugin instance. -func Plugin() *node.Plugin { - once.Do(func() { - plugin = node.NewPlugin(PluginName, node.Enabled, func(plugin *node.Plugin) { - log = logger.NewLogger(PluginName) - gracefulStop = make(chan os.Signal) +func configure(*node.Plugin) { + waitToKillTimeInSeconds = config.Node().GetInt(CfgWaitToKillTimeInSeconds) + + log = logger.NewLogger(PluginName) + gracefulStop = make(chan os.Signal) - signal.Notify(gracefulStop, syscall.SIGTERM) - signal.Notify(gracefulStop, syscall.SIGINT) + signal.Notify(gracefulStop, syscall.SIGTERM) + signal.Notify(gracefulStop, syscall.SIGINT) - go func() { - <-gracefulStop + go func() { + <-gracefulStop - log.Warnf("Received shutdown request - waiting (max %d) to finish processing ...", WaitToKillTimeInSeconds) + log.Warnf("Received shutdown request - waiting (max %d) to finish processing ...", waitToKillTimeInSeconds) - go func() { - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() + go func() { + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() - start := time.Now() - for x := range ticker.C { - secondsSinceStart := x.Sub(start).Seconds() + start := time.Now() + for x := range ticker.C { + secondsSinceStart := x.Sub(start).Seconds() - if secondsSinceStart <= WaitToKillTimeInSeconds { - processList := "" - runningBackgroundWorkers := daemon.GetRunningBackgroundWorkers() - if len(runningBackgroundWorkers) >= 1 { - sort.Strings(runningBackgroundWorkers) - processList = "(" + strings.Join(runningBackgroundWorkers, ", ") + ") " - } - log.Warnf("Received shutdown request - waiting (max %d seconds) to finish processing %s...", WaitToKillTimeInSeconds-int(secondsSinceStart), processList) - } else { - log.Error("Background processes did not terminate in time! Forcing shutdown ...") - os.Exit(1) - } + if secondsSinceStart <= float64(waitToKillTimeInSeconds) { + processList := "" + runningBackgroundWorkers := daemon.GetRunningBackgroundWorkers() + if len(runningBackgroundWorkers) >= 1 { + sort.Strings(runningBackgroundWorkers) + processList = "(" + strings.Join(runningBackgroundWorkers, ", ") + ") " } - }() + log.Warnf("Received shutdown request - waiting (max %d seconds) to finish processing %s...", waitToKillTimeInSeconds-int(secondsSinceStart), processList) + } else { + log.Error("Background processes did not terminate in time! Forcing shutdown ...") + os.Exit(1) + } + } + }() - daemon.Shutdown() - }() - }) + daemon.Shutdown() + }() +} + +// Plugin gets the plugin instance. +func Plugin() *node.Plugin { + once.Do(func() { + plugin = node.NewPlugin(PluginName, node.Enabled, configure) }) return plugin } diff --git a/tools/integration-tests/tester/framework/docker.go b/tools/integration-tests/tester/framework/docker.go index 19829696..31b9bfd5 100644 --- a/tools/integration-tests/tester/framework/docker.go +++ b/tools/integration-tests/tester/framework/docker.go @@ -86,6 +86,7 @@ func (d *DockerContainer) CreateGoShimmerPeer(config GoShimmerConfig) error { fmt.Sprintf("--autopeering.outboundUpdateIntervalMs=%d", ParaOutboundUpdateIntervalMs), fmt.Sprintf("--node.disablePlugins=%s", config.DisabledPlugins), fmt.Sprintf("--pow.difficulty=%d", ParaPoWDifficulty), + fmt.Sprintf("--gracefulshutdown.waitToKillTime=%d", ParaWaitToKill), fmt.Sprintf("--node.enablePlugins=%s", func() string { var plugins []string if config.Bootstrap { diff --git a/tools/integration-tests/tester/framework/parameters.go b/tools/integration-tests/tester/framework/parameters.go index 6d33d363..9fa13fe8 100644 --- a/tools/integration-tests/tester/framework/parameters.go +++ b/tools/integration-tests/tester/framework/parameters.go @@ -35,6 +35,8 @@ var ( ParaFaucetTokensPerRequest int64 = 1337 // ParaPoWDifficulty defines the PoW difficulty. ParaPoWDifficulty = 2 + // ParaWaitToKill defines the time to wait before killing the node. + ParaWaitToKill = 60 ) var ( diff --git a/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go b/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go index 46fbc4ca..4aec007c 100644 --- a/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go +++ b/tools/integration-tests/tester/tests/consensus/consensus_conflicts_test.go @@ -27,13 +27,16 @@ func TestConsensusFiftyFiftyOpinionSplit(t *testing.T) { // override avg. network delay to accustom integration test slowness backupFCoBAvgNetworkDelay := framework.ParaFCoBAverageNetworkDelay backupBootstrapOnEveryNode := framework.ParaBootstrapOnEveryNode + backupParaWaitToKill := framework.ParaWaitToKill framework.ParaFCoBAverageNetworkDelay = 90 framework.ParaBootstrapOnEveryNode = true + framework.ParaWaitToKill = 2 * framework.ParaFCoBAverageNetworkDelay // reset framework paras defer func() { framework.ParaFCoBAverageNetworkDelay = backupFCoBAvgNetworkDelay framework.ParaBootstrapOnEveryNode = backupBootstrapOnEveryNode + framework.ParaWaitToKill = backupParaWaitToKill }() // create two partitions with their own peers -- GitLab