mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
rpc: Closing Notifier must tear down subscriptions
* Fixes #15553 * Add a pipeline on the `Notifier`'s `codec` that propagates the `close` to `Subscription`s * Adjust `subscription_test` accordingly since closing the notifier now implies closing the subscription * This should automatically test the initial issue and also makes the tests more determistic by saving the `select`
This commit is contained in:
parent
fe070ab5c3
commit
f5ec3e00d5
2 changed files with 24 additions and 12 deletions
|
|
@ -55,16 +55,34 @@ type Notifier struct {
|
|||
subMu sync.RWMutex // guards active and inactive maps
|
||||
active map[ID]*Subscription
|
||||
inactive map[ID]*Subscription
|
||||
closed chan interface{}
|
||||
}
|
||||
|
||||
// newNotifier creates a new notifier that can be used to send subscription
|
||||
// notifications to the client.
|
||||
func newNotifier(codec ServerCodec) *Notifier {
|
||||
return &Notifier{
|
||||
n := &Notifier{
|
||||
codec: codec,
|
||||
active: make(map[ID]*Subscription),
|
||||
inactive: make(map[ID]*Subscription),
|
||||
closed: make(chan interface{}),
|
||||
}
|
||||
in := n.codec.Closed()
|
||||
go func() {
|
||||
for e := range in {
|
||||
n.closed <- e
|
||||
}
|
||||
n.subMu.Lock()
|
||||
defer n.subMu.Unlock()
|
||||
for _, subscription := range n.active {
|
||||
close(subscription.err)
|
||||
}
|
||||
for _, subscription := range n.inactive {
|
||||
close(subscription.err)
|
||||
}
|
||||
close(n.closed)
|
||||
}()
|
||||
return n
|
||||
}
|
||||
|
||||
// NotifierFromContext returns the Notifier value stored in ctx, if any.
|
||||
|
|
@ -104,7 +122,7 @@ func (n *Notifier) Notify(id ID, data interface{}) error {
|
|||
|
||||
// Closed returns a channel that is closed when the RPC connection is closed.
|
||||
func (n *Notifier) Closed() <-chan interface{} {
|
||||
return n.codec.Closed()
|
||||
return n.closed
|
||||
}
|
||||
|
||||
// unsubscribe a subscription.
|
||||
|
|
|
|||
|
|
@ -72,16 +72,10 @@ func (s *NotificationTestService) SomeSubscription(ctx context.Context, n, val i
|
|||
}
|
||||
}
|
||||
|
||||
select {
|
||||
case <-notifier.Closed():
|
||||
<-subscription.Err()
|
||||
s.mu.Lock()
|
||||
s.unsubscribed = true
|
||||
s.mu.Unlock()
|
||||
case <-subscription.Err():
|
||||
s.mu.Lock()
|
||||
s.unsubscribed = true
|
||||
s.mu.Unlock()
|
||||
}
|
||||
}()
|
||||
|
||||
return subscription, nil
|
||||
|
|
|
|||
Loading…
Reference in a new issue