mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-02-16 11:16:30 +00:00
Merge pull request #3532 from nspcc-dev/fix/ws-client-subscription-panic
rpcclient/WS: fix data race on concurrent (un)subscription
This commit is contained in:
commit
c6ed92a169
1 changed files with 20 additions and 1 deletions
|
@ -960,6 +960,14 @@ func (c *WSClient) UnsubscribeAll() error {
|
||||||
// after WS RPC unsubscription request is completed. Until then the subscriber channel
|
// after WS RPC unsubscription request is completed. Until then the subscriber channel
|
||||||
// may still receive WS notifications.
|
// may still receive WS notifications.
|
||||||
func (c *WSClient) performUnsubscription(id string) error {
|
func (c *WSClient) performUnsubscription(id string) error {
|
||||||
|
c.subscriptionsLock.RLock()
|
||||||
|
rcvrWas, ok := c.subscriptions[id]
|
||||||
|
c.subscriptionsLock.RUnlock()
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return errors.New("no subscription with this ID")
|
||||||
|
}
|
||||||
|
|
||||||
var resp bool
|
var resp bool
|
||||||
if err := c.performRequest("unsubscribe", []any{id}, &resp); err != nil {
|
if err := c.performRequest("unsubscribe", []any{id}, &resp); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -975,6 +983,15 @@ func (c *WSClient) performUnsubscription(id string) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("no subscription with this ID")
|
return errors.New("no subscription with this ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanUpSubscriptions := true
|
||||||
|
if rcvrWas.Receiver() != rcvr.Receiver() {
|
||||||
|
// concurrent subscription has been done and been overwritten; this
|
||||||
|
// is not this routine's subscription, cleanup only receivers map
|
||||||
|
rcvr = rcvrWas
|
||||||
|
cleanUpSubscriptions = false
|
||||||
|
}
|
||||||
|
|
||||||
ch := rcvr.Receiver()
|
ch := rcvr.Receiver()
|
||||||
ids := c.receivers[ch]
|
ids := c.receivers[ch]
|
||||||
for i, rcvrID := range ids {
|
for i, rcvrID := range ids {
|
||||||
|
@ -988,7 +1005,9 @@ func (c *WSClient) performUnsubscription(id string) error {
|
||||||
} else {
|
} else {
|
||||||
c.receivers[ch] = ids
|
c.receivers[ch] = ids
|
||||||
}
|
}
|
||||||
delete(c.subscriptions, id)
|
if cleanUpSubscriptions {
|
||||||
|
delete(c.subscriptions, id)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue