Skip to content

Commit

Permalink
morph: support reloading morph endpoints with SIGHUP
Browse files Browse the repository at this point in the history
Add a new function `Client.Reload` that passes the `WithEndpoints` option and
closes the client if there is no endpoint in the config to which the client is
connected.
Add docs.

Closes #1871.

Signed-off-by: Andrey Butusov <[email protected]>
  • Loading branch information
End-rey committed Nov 5, 2024
1 parent bfb5806 commit f92c1b7
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ attribute, which is used for container domain name in NNS contracts (#2954)
- `neofs-cli control object revive` command (#2968)
- `--disable-auto-gen-tag` flag for gendoc command (#2983)
- Docs files for cli commands to the `docs/cli-commands` folder (#2983)
- Reloading morph endpoints with SIGHUP (#2998)

### Fixed
- Do not search for tombstones when handling their expiration, use local indexes instead (#2929)
Expand Down
4 changes: 4 additions & 0 deletions cmd/neofs-node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,10 @@ func (c *cfg) configWatcher(ctx context.Context) {
continue
}

// Morph

c.cli.Reload(client.WithEndpoints(c.morph.endpoints))

Check warning on line 876 in cmd/neofs-node/config.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-node/config.go#L875-L876

Added lines #L875 - L876 were not covered by tests
c.log.Info("configuration has been reloaded successfully")
case <-ctx.Done():
return
Expand Down
8 changes: 6 additions & 2 deletions docs/sighup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ Available for reconfiguration fields:

```yml
head_timeout:
cache_size:
cache_time:
replication_cooldown:
object_batch_size:
max_workers:
Expand All @@ -34,3 +32,9 @@ comparing paths from `shard.blobstor` section. After this we have 3 sets:
| Changed section | Actions |
|-----------------|----------------------------------------------------------------------------------------------------------------------|
| `path` | If `path` is different, metabase is closed and opened with a new path. All other configuration will also be updated. |

### Morph

| Changed section | Actions |
|-----------------|--------------------------------------------------------------------------------------------------------------------|
| `endpoints` | If in the `endpoints` there is no endpoint that the client is connected to, try connecting to another endpoint N3. |
3 changes: 2 additions & 1 deletion pkg/morph/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ type Client struct {

cfg cfg

endpoints []string
endpointsLock *sync.RWMutex
endpoints []string

subs subscriptions

Expand Down
13 changes: 7 additions & 6 deletions pkg/morph/client/constructor.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,13 @@ func New(key *keys.PrivateKey, opts ...Option) (*Client, error) {

var (
cli = &Client{
cache: newClientCache(),
logger: cfg.logger,
acc: acc,
accAddr: accAddr,
cfg: *cfg,
closeChan: make(chan struct{}),
cache: newClientCache(),
logger: cfg.logger,
acc: acc,
accAddr: accAddr,
cfg: *cfg,
endpointsLock: &sync.RWMutex{},
closeChan: make(chan struct{}),

Check warning on line 117 in pkg/morph/client/constructor.go

View check run for this annotation

Codecov / codecov/patch

pkg/morph/client/constructor.go#L111-L117

Added lines #L111 - L117 were not covered by tests
subs: subscriptions{
notifyChan: make(chan *state.ContainedNotificationEvent),
blockChan: make(chan *block.Block),
Expand Down
3 changes: 3 additions & 0 deletions pkg/morph/client/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func (c *Client) switchRPC() *connection {
}

func (c *Client) connEndpoints() *connection {
c.endpointsLock.RLock()
defer c.endpointsLock.RUnlock()

Check warning on line 38 in pkg/morph/client/multi.go

View check run for this annotation

Codecov / codecov/patch

pkg/morph/client/multi.go#L36-L38

Added lines #L36 - L38 were not covered by tests
// Iterate endpoints.
for _, e := range c.endpoints {
conn, err := c.newConnection(e)
Expand Down
31 changes: 31 additions & 0 deletions pkg/morph/client/reload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package client

import "slices"

// Reload allows runtime reconfiguration for WithEndpoints parameter.
func (c *Client) Reload(opts ...Option) {
cfg := new(cfg)
for _, o := range opts {
o(cfg)
}

Check warning on line 10 in pkg/morph/client/reload.go

View check run for this annotation

Codecov / codecov/patch

pkg/morph/client/reload.go#L6-L10

Added lines #L6 - L10 were not covered by tests

c.endpointsLock.Lock()

c.cfg.endpoints = cfg.endpoints
c.endpoints = cfg.endpoints

c.endpointsLock.Unlock()

var conn = c.conn.Load()
if conn == nil {
return
}
currentEndpoint := conn.client.Endpoint()

// RPC reconnections are costly for node, so we avoid them
// by using the current connection while it's alive
// if the current endpoint is present in the config
if !slices.Contains(cfg.endpoints, currentEndpoint) {
conn.client.Close()
}

Check warning on line 30 in pkg/morph/client/reload.go

View check run for this annotation

Codecov / codecov/patch

pkg/morph/client/reload.go#L12-L30

Added lines #L12 - L30 were not covered by tests
}

0 comments on commit f92c1b7

Please sign in to comment.