mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-30 11:31:29 +02:00
[client] Make tunnel notifier Close wait for queued events to drain
Close previously returned immediately after marking the notifier closed, so deliverLoop could still be invoking listener/DNS callbacks after Close returned. Close now blocks on a completion channel that deliverLoop closes once it has drained the queue and exited.
This commit is contained in:
@@ -32,6 +32,7 @@ type Notifier struct {
|
||||
cond *sync.Cond
|
||||
queue *list.List
|
||||
closed bool
|
||||
done chan struct{}
|
||||
|
||||
listener listener.NetworkChangeListener
|
||||
dnsManager dns.IosDnsManager
|
||||
@@ -40,6 +41,7 @@ type Notifier struct {
|
||||
func New(l listener.NetworkChangeListener, dm dns.IosDnsManager) *Notifier {
|
||||
n := &Notifier{
|
||||
queue: list.New(),
|
||||
done: make(chan struct{}),
|
||||
listener: l,
|
||||
dnsManager: dm,
|
||||
}
|
||||
@@ -64,11 +66,14 @@ func (n *Notifier) ApplyDns(config string) {
|
||||
n.enqueue(event{kind: eventDNS, payload: config})
|
||||
}
|
||||
|
||||
// Close stops accepting new events and blocks until the delivery loop has
|
||||
// drained all queued events and exited.
|
||||
func (n *Notifier) Close() {
|
||||
n.mu.Lock()
|
||||
n.closed = true
|
||||
n.cond.Signal()
|
||||
n.mu.Unlock()
|
||||
<-n.done
|
||||
}
|
||||
|
||||
func (n *Notifier) enqueue(ev event) {
|
||||
@@ -82,6 +87,7 @@ func (n *Notifier) enqueue(ev event) {
|
||||
}
|
||||
|
||||
func (n *Notifier) deliverLoop() {
|
||||
defer close(n.done)
|
||||
for {
|
||||
n.mu.Lock()
|
||||
for n.queue.Len() == 0 && !n.closed {
|
||||
|
||||
@@ -183,7 +183,7 @@ func TestCloseDrainsQueue(t *testing.T) {
|
||||
}
|
||||
n.Close()
|
||||
|
||||
require.Eventually(t, func() bool { return rec.count() == events }, 5*time.Second, time.Millisecond)
|
||||
require.Equal(t, events, rec.count(), "Close must not return before all queued events are delivered")
|
||||
|
||||
n.OnNetworkChanged("after-close")
|
||||
n.ApplyDns("after-close")
|
||||
|
||||
Reference in New Issue
Block a user