diff --git a/CHANGELOG.md b/CHANGELOG.md index bb8ad51d8d..289725febf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ Changelog for FrostFS Node - Possible deadlock in write-cache (#2239) - Fix `*_req_count` and `*_req_count_success` metric values (#2241) - Storage ID update by write-cache (#2244) +- `neo-go` client deadlock on subscription restoration (#2244) ### Removed ### Updated diff --git a/pkg/morph/client/notifications.go b/pkg/morph/client/notifications.go index 63e5a5c8aa..2afeebb832 100644 --- a/pkg/morph/client/notifications.go +++ b/pkg/morph/client/notifications.go @@ -211,6 +211,29 @@ func (c *Client) restoreSubscriptions(cli *rpcclient.WSClient, endpoint 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 if c.subscribedToNewBlocks { _, err = cli.SubscribeForNewBlocks(nil)