Fix notification manager deadlock in Stop()
Critical deadlock fix: - Stop() was holding n.mu lock while calling queue.Stop() - queue.Stop() waits for worker goroutines to finish - Worker goroutines call ProcessQueuedNotification() which needs n.mu lock - This created a classic lock-order deadlock Fix: - Unlock n.mu before calling queue.Stop() - Relock after queue shutdown completes - Workers can now finish and acquire lock as needed This resolves 30-second test timeouts in notifications package. Tests now complete in <1s instead of timing out at 30s.
This commit is contained in:
parent
fbeaa91fc0
commit
d9e0505394
1 changed files with 13 additions and 3 deletions
|
|
@ -2537,16 +2537,26 @@ func (n *NotificationManager) cleanupOldNotificationRecords() {
|
||||||
// Stop gracefully stops the notification manager
|
// Stop gracefully stops the notification manager
|
||||||
func (n *NotificationManager) Stop() {
|
func (n *NotificationManager) Stop() {
|
||||||
n.mu.Lock()
|
n.mu.Lock()
|
||||||
defer n.mu.Unlock()
|
|
||||||
|
|
||||||
// Stop cleanup goroutine
|
// Stop cleanup goroutine
|
||||||
close(n.stopCleanup)
|
close(n.stopCleanup)
|
||||||
|
|
||||||
|
// Get queue reference before unlocking
|
||||||
|
queue := n.queue
|
||||||
|
|
||||||
|
// Unlock before stopping queue to avoid deadlock with queue workers
|
||||||
|
// that may need to acquire n.mu during ProcessQueuedNotification
|
||||||
|
n.mu.Unlock()
|
||||||
|
|
||||||
// Stop the notification queue if it exists
|
// Stop the notification queue if it exists
|
||||||
if n.queue != nil {
|
if queue != nil {
|
||||||
n.queue.Stop()
|
queue.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Relock for remaining cleanup
|
||||||
|
n.mu.Lock()
|
||||||
|
defer n.mu.Unlock()
|
||||||
|
|
||||||
// Cancel any pending group timer
|
// Cancel any pending group timer
|
||||||
if n.groupTimer != nil {
|
if n.groupTimer != nil {
|
||||||
n.groupTimer.Stop()
|
n.groupTimer.Stop()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue