feat(notifications): library health reaches admins, coalesced (#5341)
release / govulncheck (push) Successful in 18s
release / web (push) Successful in 1m22s
release / go (push) Successful in 1m43s
release / integration (push) Successful in 4m56s
release / android (push) Successful in 5m16s
release / Build signed APK (releases and dev) (push) Successful in 5m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 15s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 18s
release / web (push) Successful in 1m22s
release / go (push) Successful in 1m43s
release / integration (push) Successful in 4m56s
release / android (push) Successful in 5m16s
release / Build signed APK (releases and dev) (push) Successful in 5m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 15s
release / Verify release artifacts (tag releases only) (push) Skipped
- A failed scan run sends scan_failed. Each failure adds to the count and the notice shows the latest error. A scan cut short by shutdown says nothing. - Marking tracks missing sends tracks_missing with a running count. - A duplicate sweep that proposes a group it had not proposed before sends duplicates_found, counting everything awaiting review. A sweep that only re-finds known groups stays quiet, so a read notice isn't repeated every sweep (CountDuplicateGroupsDetectedSince). - A playback-error report sends playback_errors, counting the unresolved errors (CountUnresolvedPlaybackErrors). The library package gets its notifier as a package-level SetNotifier beside SetEventBus, for the same reason the bus is package-level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/notifications"
|
||||
)
|
||||
|
||||
// Package-level notifier for library-health notices to admins (M489): a
|
||||
// scan that failed, tracks gone missing, new duplicates. Set once at startup
|
||||
// beside SetEventBus, for the same reason the bus is package-level. Nil, as in
|
||||
// tests that never set it, means nobody is told.
|
||||
var (
|
||||
notifierMu sync.RWMutex
|
||||
notifier *notifications.Notifier
|
||||
)
|
||||
|
||||
// SetNotifier wires the notifications inbox into the library package.
|
||||
func SetNotifier(n *notifications.Notifier) {
|
||||
notifierMu.Lock()
|
||||
defer notifierMu.Unlock()
|
||||
notifier = n
|
||||
}
|
||||
|
||||
// notifyAdmins tells every admin about a library-health event. These kinds
|
||||
// coalesce, so a burst is one unread notice with a running count.
|
||||
func notifyAdmins(ctx context.Context, kind notifications.Kind, p notifications.Payload) {
|
||||
notifierMu.RLock()
|
||||
n := notifier
|
||||
notifierMu.RUnlock()
|
||||
n.NotifyLogged(ctx, kind, notifications.ToAdmins(pgtype.UUID{}), p.Map())
|
||||
}
|
||||
|
||||
// notifyScanFinished tells admins a scan run ended in error. A scan cut short
|
||||
// by shutdown is not a failure anyone needs telling about.
|
||||
func notifyScanFinished(ctx context.Context, errMsg string) {
|
||||
if errMsg == "" || ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
notifyAdmins(ctx, notifications.KindScanFailed, notifications.Payload{Count: 1, Detail: errMsg})
|
||||
}
|
||||
Reference in New Issue
Block a user