[#1648] morph: Change endpoint priority order

The lowest value means the highest priority.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2022-08-02 14:31:21 +03:00 committed by Pavel Karpy
parent 2467be0117
commit a97dee008c
10 changed files with 67 additions and 17 deletions

View file

@ -7,6 +7,8 @@ Changelog for NeoFS Node
### Changed ### Changed
- Priority order in the Morph client (#1648)
### Fixed ### Fixed
- Losing request context in eACL response checks (#1595) - Losing request context in eACL response checks (#1595)
@ -28,6 +30,9 @@ Changelog for NeoFS Node
- `google.golang.org/grpc` to `v1.48.0` - `google.golang.org/grpc` to `v1.48.0`
### Updating from v0.30.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 (생일도, 生日島) ## [0.30.0] - 2022-07-22 - Saengildo (생일도, 生日島)

View file

@ -24,6 +24,9 @@ const (
// MaxConnPerHostDefault is a default maximum of connections per host of the morph client. // MaxConnPerHostDefault is a default maximum of connections per host of the morph client.
MaxConnPerHostDefault = 10 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 // RPCEndpoint returns list of the values of "rpc_endpoint" config parameter
@ -41,9 +44,14 @@ func RPCEndpoint(c *config.Config) []client.Endpoint {
break break
} }
priority := int(config.IntSafe(s, "priority"))
if priority <= 0 {
priority = PriorityDefault
}
es = append(es, client.Endpoint{ es = append(es, client.Endpoint{
Address: addr, Address: addr,
Priority: int(config.IntSafe(s, "priority")), Priority: priority,
}) })
} }

View file

@ -24,8 +24,8 @@ func TestMorphSection(t *testing.T) {
var ( var (
rpcs = []client.Endpoint{ rpcs = []client.Endpoint{
{"wss://rpc1.morph.fs.neo.org:40341/ws", 2}, {"wss://rpc1.morph.fs.neo.org:40341/ws", 1},
{"wss://rpc2.morph.fs.neo.org:40341/ws", 1}, {"wss://rpc2.morph.fs.neo.org:40341/ws", 2},
} }
) )

View file

@ -63,9 +63,9 @@ NEOFS_CONTRACTS_PROXY=ad7c6b55b737b696e5c82c85445040964a03e97f
NEOFS_MORPH_DIAL_TIMEOUT=30s NEOFS_MORPH_DIAL_TIMEOUT=30s
NEOFS_MORPH_DISABLE_CACHE=true NEOFS_MORPH_DISABLE_CACHE=true
NEOFS_MORPH_RPC_ENDPOINT_0_ADDRESS="wss://rpc1.morph.fs.neo.org:40341/ws" 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_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 # API Client section
NEOFS_APICLIENT_DIAL_TIMEOUT=15s NEOFS_APICLIENT_DIAL_TIMEOUT=15s

View file

@ -103,11 +103,11 @@
"rpc_endpoint": [ "rpc_endpoint": [
{ {
"address": "wss://rpc1.morph.fs.neo.org:40341/ws", "address": "wss://rpc1.morph.fs.neo.org:40341/ws",
"priority": 2 "priority": 0
}, },
{ {
"address": "wss://rpc2.morph.fs.neo.org:40341/ws", "address": "wss://rpc2.morph.fs.neo.org:40341/ws",
"priority": 1 "priority": 2
} }
] ]
}, },

View file

@ -84,9 +84,9 @@ morph:
disable_cache: true # do not use TTL cache for side chain GET operations 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 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 - address: wss://rpc1.morph.fs.neo.org:40341/ws
priority: 2 priority: 0
- address: wss://rpc2.morph.fs.neo.org:40341/ws - address: wss://rpc2.morph.fs.neo.org:40341/ws
priority: 1 priority: 2
apiclient: apiclient:
dial_timeout: 15s # timeout for NEOFS API client connection dial_timeout: 15s # timeout for NEOFS API client connection

View file

@ -134,9 +134,9 @@ morph:
disable_cache: true disable_cache: true
rpc_endpoint: rpc_endpoint:
- address: wss://rpc1.morph.fs.neo.org:40341/ws - address: wss://rpc1.morph.fs.neo.org:40341/ws
priority: 2
- address: wss://rpc2.morph.fs.neo.org:40341/ws
priority: 1 priority: 1
- address: wss://rpc2.morph.fs.neo.org:40341/ws
priority: 2
``` ```
| Parameter | Type | Default value | Description | | Parameter | Type | Default value | Description |
@ -147,9 +147,9 @@ morph:
## `rpc_endpoint` subsection ## `rpc_endpoint` subsection
| Parameter | Type | Default value | Description | | Parameter | Type | Default value | Description |
|------------|----------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------| |------------|----------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `address` | `string` | | _WebSocket_ N3 endpoint. | | `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. | | `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 # `storage` section

View file

@ -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" // config name left unchanged for compatibility, may be its better to rename it to "endpoints" or "clients"
var endpoints []client.Endpoint var endpoints []client.Endpoint
// defaultPriority is a default endpoint priority
const defaultPriority = 1
section := p.name + ".endpoint.client" section := p.name + ".endpoint.client"
for i := 0; ; i++ { for i := 0; ; i++ {
addr := p.cfg.GetString(fmt.Sprintf("%s.%d.%s", section, i, "address")) 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 break
} }
priority := p.cfg.GetInt(section + ".priority")
if priority <= 0 {
priority = defaultPriority
}
endpoints = append(endpoints, client.Endpoint{ endpoints = append(endpoints, client.Endpoint{
Address: addr, Address: addr,
Priority: p.cfg.GetInt(section + ".priority"), Priority: priority,
}) })
} }

View file

@ -19,7 +19,7 @@ type endpoints struct {
func (e *endpoints) init(ee []Endpoint) { func (e *endpoints) init(ee []Endpoint) {
sort.SliceStable(ee, func(i, j int) bool { 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 e.curr = 0

View file

@ -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
}
}