diff --git a/CHANGELOG.md b/CHANGELOG.md index 126c472b79..750414213f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Changelog for NeoFS Node ### Changed +- Priority order in the Morph client (#1648) + ### Fixed - Losing request context in eACL response checks (#1595) @@ -28,6 +30,9 @@ Changelog for NeoFS Node - `google.golang.org/grpc` to `v1.48.0` ### Updating from v0.30.0 +Change `morph.endpoint.client` priority values using the following rule: +the higher the priority the lower the value (non-specified or `0` values are +interpreted as the highest priority -- `1`). ## [0.30.0] - 2022-07-22 - Saengildo (생일도, 生日島) diff --git a/cmd/neofs-node/config/morph/config.go b/cmd/neofs-node/config/morph/config.go index 63774aba4b..83c7be33e4 100644 --- a/cmd/neofs-node/config/morph/config.go +++ b/cmd/neofs-node/config/morph/config.go @@ -24,6 +24,9 @@ const ( // MaxConnPerHostDefault is a default maximum of connections per host of the morph client. MaxConnPerHostDefault = 10 + + // PriorityDefault is a default endpoint priority for the morph client. + PriorityDefault = 1 ) // RPCEndpoint returns list of the values of "rpc_endpoint" config parameter @@ -41,9 +44,14 @@ func RPCEndpoint(c *config.Config) []client.Endpoint { break } + priority := int(config.IntSafe(s, "priority")) + if priority <= 0 { + priority = PriorityDefault + } + es = append(es, client.Endpoint{ Address: addr, - Priority: int(config.IntSafe(s, "priority")), + Priority: priority, }) } diff --git a/cmd/neofs-node/config/morph/config_test.go b/cmd/neofs-node/config/morph/config_test.go index 5fc82c9e10..fa26e1044f 100644 --- a/cmd/neofs-node/config/morph/config_test.go +++ b/cmd/neofs-node/config/morph/config_test.go @@ -24,8 +24,8 @@ func TestMorphSection(t *testing.T) { var ( rpcs = []client.Endpoint{ - {"wss://rpc1.morph.fs.neo.org:40341/ws", 2}, - {"wss://rpc2.morph.fs.neo.org:40341/ws", 1}, + {"wss://rpc1.morph.fs.neo.org:40341/ws", 1}, + {"wss://rpc2.morph.fs.neo.org:40341/ws", 2}, } ) diff --git a/config/example/node.env b/config/example/node.env index 2f91b3696c..59b02e2014 100644 --- a/config/example/node.env +++ b/config/example/node.env @@ -63,9 +63,9 @@ NEOFS_CONTRACTS_PROXY=ad7c6b55b737b696e5c82c85445040964a03e97f NEOFS_MORPH_DIAL_TIMEOUT=30s NEOFS_MORPH_DISABLE_CACHE=true NEOFS_MORPH_RPC_ENDPOINT_0_ADDRESS="wss://rpc1.morph.fs.neo.org:40341/ws" -NEOFS_MORPH_RPC_ENDPOINT_0_PRIORITY=2 +NEOFS_MORPH_RPC_ENDPOINT_0_PRIORITY=0 NEOFS_MORPH_RPC_ENDPOINT_1_ADDRESS="wss://rpc2.morph.fs.neo.org:40341/ws" -NEOFS_MORPH_RPC_ENDPOINT_1_PRIORITY=1 +NEOFS_MORPH_RPC_ENDPOINT_1_PRIORITY=2 # API Client section NEOFS_APICLIENT_DIAL_TIMEOUT=15s diff --git a/config/example/node.json b/config/example/node.json index 0e19233ca0..6516cd4e97 100644 --- a/config/example/node.json +++ b/config/example/node.json @@ -103,11 +103,11 @@ "rpc_endpoint": [ { "address": "wss://rpc1.morph.fs.neo.org:40341/ws", - "priority": 2 + "priority": 0 }, { "address": "wss://rpc2.morph.fs.neo.org:40341/ws", - "priority": 1 + "priority": 2 } ] }, diff --git a/config/example/node.yaml b/config/example/node.yaml index 7fbd88d238..88a2151ca0 100644 --- a/config/example/node.yaml +++ b/config/example/node.yaml @@ -84,9 +84,9 @@ morph: disable_cache: true # do not use TTL cache for side chain GET operations rpc_endpoint: # side chain NEO RPC endpoints; are shuffled and used one by one until the first success - address: wss://rpc1.morph.fs.neo.org:40341/ws - priority: 2 + priority: 0 - address: wss://rpc2.morph.fs.neo.org:40341/ws - priority: 1 + priority: 2 apiclient: dial_timeout: 15s # timeout for NEOFS API client connection diff --git a/docs/storage-node-configuration.md b/docs/storage-node-configuration.md index 57f28b189e..aea08be190 100644 --- a/docs/storage-node-configuration.md +++ b/docs/storage-node-configuration.md @@ -134,9 +134,9 @@ morph: disable_cache: true rpc_endpoint: - address: wss://rpc1.morph.fs.neo.org:40341/ws - priority: 2 - - address: wss://rpc2.morph.fs.neo.org:40341/ws priority: 1 + - address: wss://rpc2.morph.fs.neo.org:40341/ws + priority: 2 ``` | Parameter | Type | Default value | Description | @@ -146,10 +146,10 @@ morph: | `rpc_endpoint` | list of [endpoint descriptions](#rpc_endpoint-subsection) | | Array of endpoint descriptions. | ## `rpc_endpoint` subsection -| Parameter | Type | Default value | Description | -|------------|----------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------| -| `address` | `string` | | _WebSocket_ N3 endpoint. | -| `priority` | `int` | `0` | Priority of an endpoint. Endpoint with a higher priority has more chance of being used. Endpoints with equal priority are iterated over randomly. | +| Parameter | Type | Default value | Description | +|------------|----------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `address` | `string` | | _WebSocket_ N3 endpoint. | +| `priority` | `int` | `1` | Priority of an endpoint. Endpoint with a higher priority (lower configuration value) has more chance of being used. Endpoints with equal priority are iterated over randomly; a negative priority is interpreted as `1`. | # `storage` section diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 0c6f169215..4806fd7c66 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -961,6 +961,9 @@ func createClient(ctx context.Context, p *chainParams, errChan chan<- error) (*c // config name left unchanged for compatibility, may be its better to rename it to "endpoints" or "clients" var endpoints []client.Endpoint + // defaultPriority is a default endpoint priority + const defaultPriority = 1 + section := p.name + ".endpoint.client" for i := 0; ; i++ { addr := p.cfg.GetString(fmt.Sprintf("%s.%d.%s", section, i, "address")) @@ -968,9 +971,14 @@ func createClient(ctx context.Context, p *chainParams, errChan chan<- error) (*c break } + priority := p.cfg.GetInt(section + ".priority") + if priority <= 0 { + priority = defaultPriority + } + endpoints = append(endpoints, client.Endpoint{ Address: addr, - Priority: p.cfg.GetInt(section + ".priority"), + Priority: priority, }) } diff --git a/pkg/morph/client/multi.go b/pkg/morph/client/multi.go index 0a5d8dc69d..aab2b1d95d 100644 --- a/pkg/morph/client/multi.go +++ b/pkg/morph/client/multi.go @@ -19,7 +19,7 @@ type endpoints struct { func (e *endpoints) init(ee []Endpoint) { sort.SliceStable(ee, func(i, j int) bool { - return ee[i].Priority > ee[j].Priority + return ee[i].Priority < ee[j].Priority }) e.curr = 0 diff --git a/pkg/morph/client/multy_test.go b/pkg/morph/client/multy_test.go new file mode 100644 index 0000000000..4bc38c70ca --- /dev/null +++ b/pkg/morph/client/multy_test.go @@ -0,0 +1,29 @@ +package client + +import ( + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestInitEndpoints(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + + ee := make([]Endpoint, 100) + for i := range ee { + ee[i].Priority = rand.Int() + } + + var eeInternal endpoints + eeInternal.init(ee) + + prevValue := eeInternal.list[0].Priority + + for _, e := range eeInternal.list { + require.True(t, prevValue <= e.Priority) + + prevValue = e.Priority + } +}