[#2244] node: Fix subscriptions lock

Subscribing without async listening could lead to a dead-lock in the
`neo-go` client.

Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
This commit is contained in:
Pavel Karpy 2023-02-07 19:35:15 +03:00 committed by fyrchik
parent 07ec51ea60
commit 95ee905861
2 changed files with 24 additions and 0 deletions

View file

@ -36,6 +36,7 @@ Changelog for FrostFS Node
- Possible deadlock in write-cache (#2239) - Possible deadlock in write-cache (#2239)
- Fix `*_req_count` and `*_req_count_success` metric values (#2241) - Fix `*_req_count` and `*_req_count_success` metric values (#2241)
- Storage ID update by write-cache (#2244) - Storage ID update by write-cache (#2244)
- `neo-go` client deadlock on subscription restoration (#2244)
### Removed ### Removed
### Updated ### Updated

View file

@ -211,6 +211,29 @@ func (c *Client) restoreSubscriptions(cli *rpcclient.WSClient, endpoint string)
id string id string
) )
stopCh := make(chan struct{})
defer close(stopCh)
// neo-go WS client says to _always_ read notifications
// from its channel. Subscribing to any notification
// while not reading them in another goroutine may
// lead to a dead-lock, thus that async side notification
// listening while restoring subscriptions
go func() {
for {
select {
case <-stopCh:
return
case n, ok := <-cli.Notifications:
if !ok {
return
}
c.notifications <- n
}
}
}()
// new block events restoration // new block events restoration
if c.subscribedToNewBlocks { if c.subscribedToNewBlocks {
_, err = cli.SubscribeForNewBlocks(nil) _, err = cli.SubscribeForNewBlocks(nil)