Improve notification sound throttling and delivery reliability
Refactor notification sound playback to use per-bucket throttling, adjust socket warmup, and ensure push notifications are sent even if the client is considered connected.
This commit is contained in:
@@ -118,7 +118,13 @@ class NotificationPlayer {
|
||||
|
||||
// ---- Shared state ----
|
||||
private unlocked = false;
|
||||
private lastPlayAt = 0;
|
||||
// #628: per-bucket throttle timestamps. Was a single global value,
|
||||
// which coupled channels: lowering the order throttle to 800ms
|
||||
// caused rapid order chimes to keep refreshing the global timestamp
|
||||
// and starve meeting/note chimes (whose 3s window kept restarting).
|
||||
// Bucketing isolates each channel so order bursts can't mute
|
||||
// meeting/note alerts and vice versa.
|
||||
private lastPlayAtByBucket = new Map<string, number>();
|
||||
private hintDispatched = false;
|
||||
|
||||
private get useIos(): boolean {
|
||||
@@ -334,16 +340,34 @@ class NotificationPlayer {
|
||||
*/
|
||||
play(
|
||||
soundId: NotificationSoundId,
|
||||
opts: { vibrate?: boolean; bypassThrottle?: boolean } = {},
|
||||
opts: {
|
||||
vibrate?: boolean;
|
||||
bypassThrottle?: boolean;
|
||||
// #628: per-call throttle override. Order chimes drop to 800ms
|
||||
// so a small burst of incoming orders (rare but real during
|
||||
// service rushes) still rings for each one instead of swallowing
|
||||
// every order after the first for the next 3 seconds. Other
|
||||
// channels keep the original 3000ms coalescing window so a
|
||||
// single meeting fanout that touches several listeners doesn't
|
||||
// produce a buzzy double-chime.
|
||||
throttleMs?: number;
|
||||
// #628: throttle bucket key. Defaults to "default" so legacy
|
||||
// callers behave as before. Callers that want isolated coalescing
|
||||
// (e.g. "order" vs "meeting" vs "note") pass distinct buckets so
|
||||
// a burst on one channel can't extend the silence window of
|
||||
// another channel.
|
||||
throttleBucket?: string;
|
||||
} = {},
|
||||
): void {
|
||||
// Throttle: at most one sound every 3s to coalesce bursts of
|
||||
// notifications into a single chime. Settings "Test sound"
|
||||
// bypasses this so users can audition multiple sounds quickly.
|
||||
const now =
|
||||
typeof performance !== "undefined" ? performance.now() : Date.now();
|
||||
if (!opts.bypassThrottle) {
|
||||
if (now - this.lastPlayAt < 3000) return;
|
||||
this.lastPlayAt = now;
|
||||
const window =
|
||||
typeof opts.throttleMs === "number" ? opts.throttleMs : 3000;
|
||||
const bucket = opts.throttleBucket ?? "default";
|
||||
const last = this.lastPlayAtByBucket.get(bucket) ?? 0;
|
||||
if (now - last < window) return;
|
||||
this.lastPlayAtByBucket.set(bucket, now);
|
||||
}
|
||||
|
||||
const entry = SOUND_BY_ID.get(soundId) ?? SOUND_BY_ID.get("ding");
|
||||
|
||||
Reference in New Issue
Block a user