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