From 63e035bd8a124d9f0bf4155668190af70d5fbf7b Mon Sep 17 00:00:00 2001
From: Pavel Karpy <carpawell@nspcc.ru>
Date: Wed, 15 Dec 2021 21:03:06 +0300
Subject: [PATCH] [#1031] node: Add `maxConnPerHost` to config

It allows configuring number of neo-go client opened connections per one
host.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
---
 cmd/neofs-node/config/morph/config.go      | 14 ++++++++++++++
 cmd/neofs-node/config/morph/config_test.go |  2 ++
 config/example/node.env                    |  1 +
 config/example/node.json                   |  3 ++-
 config/example/node.yaml                   |  1 +
 5 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/cmd/neofs-node/config/morph/config.go b/cmd/neofs-node/config/morph/config.go
index 4c350efa7..8cbd9ac74 100644
--- a/cmd/neofs-node/config/morph/config.go
+++ b/cmd/neofs-node/config/morph/config.go
@@ -19,6 +19,9 @@ const (
 
 	// NotaryDepositDurationDefault is a default deposit duration.
 	NotaryDepositDurationDefault uint32 = 1000
+
+	// MaxConnPerHostDefault is a default maximum of connections per host of the morph client.
+	MaxConnPerHostDefault = 10
 )
 
 // RPCEndpoint returns list of values of "rpc_endpoint" config parameter
@@ -65,3 +68,14 @@ func DialTimeout(c *config.Config) time.Duration {
 func DisableCache(c *config.Config) bool {
 	return config.BoolSafe(c.Sub(subsection), "disable_cache")
 }
+
+// MaxConnPerHost return value of "max_connections_per_host" config
+// parameter from "morph" section.
+func MaxConnPerHost(c *config.Config) int {
+	v := config.Uint32Safe(c.Sub(subsection), "max_connections_per_host")
+	if v > 0 {
+		return int(v)
+	}
+
+	return MaxConnPerHostDefault
+}
diff --git a/cmd/neofs-node/config/morph/config_test.go b/cmd/neofs-node/config/morph/config_test.go
index 3f9946be1..3fef69a4b 100644
--- a/cmd/neofs-node/config/morph/config_test.go
+++ b/cmd/neofs-node/config/morph/config_test.go
@@ -18,6 +18,7 @@ func TestMorphSection(t *testing.T) {
 		require.Panics(t, func() { morphconfig.NotificationEndpoint(empty) })
 		require.Equal(t, morphconfig.DialTimeoutDefault, morphconfig.DialTimeout(empty))
 		require.Equal(t, false, morphconfig.DisableCache(empty))
+		require.Equal(t, 10, morphconfig.MaxConnPerHost(empty))
 	})
 
 	const path = "../../../../config/example/node"
@@ -39,6 +40,7 @@ func TestMorphSection(t *testing.T) {
 		require.Equal(t, wss, morphconfig.NotificationEndpoint(c))
 		require.Equal(t, 30*time.Second, morphconfig.DialTimeout(c))
 		require.Equal(t, true, morphconfig.DisableCache(c))
+		require.Equal(t, 11, morphconfig.MaxConnPerHost(c))
 	}
 
 	configtest.ForEachFileType(path, fileConfigTest)
diff --git a/config/example/node.env b/config/example/node.env
index e4e83f94a..abb09d5df 100644
--- a/config/example/node.env
+++ b/config/example/node.env
@@ -49,6 +49,7 @@ NEOFS_MORPH_DIAL_TIMEOUT=30s
 NEOFS_MORPH_DISABLE_CACHE=true
 NEOFS_MORPH_RPC_ENDPOINT="https://rpc1.morph.fs.neo.org:40341 https://rpc2.morph.fs.neo.org:40341"
 NEOFS_MORPH_NOTIFICATION_ENDPOINT="wss://rpc1.morph.fs.neo.org:40341/ws wss://rpc2.morph.fs.neo.org:40341/ws"
+NEOFS_MORPH_MAX_CONNECTIONS_PER_HOST=11
 
 # Main chain section (optional)
 NEOFS_MAINCHAIN_DIAL_TIMEOUT=30s
diff --git a/config/example/node.json b/config/example/node.json
index cf9538817..fdb68dea4 100644
--- a/config/example/node.json
+++ b/config/example/node.json
@@ -88,7 +88,8 @@
     "notification_endpoint": [
       "wss://rpc1.morph.fs.neo.org:40341/ws",
       "wss://rpc2.morph.fs.neo.org:40341/ws"
-    ]
+    ],
+    "max_connections_per_host": 11
   },
   "mainchain": {
     "dial_timeout": "30s",
diff --git a/config/example/node.yaml b/config/example/node.yaml
index 283bd86a8..0d8d39a7e 100644
--- a/config/example/node.yaml
+++ b/config/example/node.yaml
@@ -74,6 +74,7 @@ morph:
   notification_endpoint:  # side chain NEO RPC notification endpoints; are shuffled and used only the first non-error one
     - wss://rpc1.morph.fs.neo.org:40341/ws
     - wss://rpc2.morph.fs.neo.org:40341/ws
+  max_connections_per_host: 11  # maximum of open connections per one host
 
 mainchain:  # DEPRECATED section, is not used and not read
   dial_timeout: 30s  # timeout for main chain NEO RPC client connection