fix(sync): scan events keep instance-wide fan-out as the sanctioned BroadcastToAll
Verifying the per-user chokepoint end to end surfaced a UI regression it would have caused: web/src/header.ts runs the sitewide scan indicator on scan_progress/scan_complete events in every browser, and routing those to the triggering identity alone froze the indicator for everyone else at its page-load state (active-summary stays the load-time fallback, but live movement died). The source's own comment declares the indicator sitewide by design, and scan payloads carry no user data — job ids, file counts, progress percentages only. Resolution honors both truths: BroadcastToAll is re-added as the ONE sanctioned instance-wide fan-out, its doc comment making the decision explicit (no user-derived data; anything carrying books, notes, or annotations belongs in BroadcastToUser), and the two scan emitters use it. TestBroadcastToAllReachesEveryone pins the exception alongside TestBroadcastIsPerUser — audiences are now named decisions the compiler and the tests both enforce.
This commit is contained in:
1 parent
a431dfa10b
commit
dd963993eb
4 files changed
+77
-13
No files matched your search
@@ -402,15 +402,18 @@ func (w *Worker) processJob(job *Job) {
|
||||
Errors: errors,
|
||||
}
|
||||
|
||||
if job.Type == JobTypeScan && w.connManager != nil && job.UserID != "" {
|
||||
if job.Type == JobTypeScan && w.connManager != nil {
|
||||
// Cancelled scans announce scan_cancelled so clients reset
|
||||
// their scanning indicators; a "scan_complete" would read as
|
||||
// a finished scan.
|
||||
// Scan events are instance activity, not user data (job ids and
|
||||
// counts only) — they fan out to every client so the sitewide
|
||||
// scan indicator works for everyone. See BroadcastToAll.
|
||||
msgType := wsync.MessageTypeScanComplete
|
||||
if status == JobStatusCancelled {
|
||||
msgType = wsync.MessageTypeScanCancelled
|
||||
}
|
||||
w.connManager.BroadcastToUser(job.UserID, wsync.BroadcastMessage{
|
||||
w.connManager.BroadcastToAll(wsync.BroadcastMessage{
|
||||
Type: msgType,
|
||||
Data: map[string]interface{}{
|
||||
"job_id": job.ID,
|
||||
@@ -464,8 +467,10 @@ func (w *Worker) processScanJob(job *Job) (interface{}, error) {
|
||||
result.NewItems = newItems
|
||||
result.Errors = errors
|
||||
}
|
||||
// Broadcast via WebSocket to user
|
||||
if w.connManager != nil && job.UserID != "" {
|
||||
// Broadcast scan progress to every connected client — instance
|
||||
// activity, no user data (see BroadcastToAll). The sitewide
|
||||
// header indicator runs on these events.
|
||||
if w.connManager != nil {
|
||||
msg := wsync.BroadcastMessage{
|
||||
Type: wsync.MessageTypeScanProgress,
|
||||
Data: map[string]interface{}{
|
||||
@@ -477,7 +482,7 @@ func (w *Worker) processScanJob(job *Job) (interface{}, error) {
|
||||
},
|
||||
}
|
||||
|
||||
w.connManager.BroadcastToUser(job.UserID, msg)
|
||||
w.connManager.BroadcastToAll(msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user