mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
fix(guest): serialize concurrent queue-mutation playback per bot
The queue-mutating playback routes (play-now-song, play-next-song, add-song, play-at) read queue position synchronously, mutate the queue, then await resolveAndPlay() which suspends at an async URL fetch before player.play(). With no serialization, two concurrent requests (normal in login-less guest mode) interleave: the audible song (decided by URL-fetch latency) can disagree with queue.currentIndex (decided by sync-block ordering), corrupting "now playing" and causing skipped/duplicate songs. Add a per-bot async serializer (BotInstance.runExclusive) and wrap the critical region of all four routes in it. Single-request behavior and every response shape / validation 400 are preserved; only the critical region moved inside runExclusive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
43c0175334
commit
a1a70dea5d
3 files changed
+204
-65
No files matched your search
@@ -78,6 +78,7 @@ export class BotInstance extends EventEmitter {
|
||||
private fmProvider: MusicProvider | null = null;
|
||||
/** Results of the most recent !search, for "#N" selection (issue #90). */
|
||||
private lastSearchResults: Song[] = [];
|
||||
private playGate: Promise<unknown> = Promise.resolve();
|
||||
|
||||
constructor(options: BotInstanceOptions) {
|
||||
super();
|
||||
@@ -1051,6 +1052,14 @@ export class BotInstance extends EventEmitter {
|
||||
return input;
|
||||
}
|
||||
|
||||
/** Serialize queue-mutation + play sequences so concurrent requests can't
|
||||
* interleave (audible track must match queue.currentIndex). */
|
||||
runExclusive<T>(fn: () => Promise<T>): Promise<T> {
|
||||
const next = this.playGate.then(fn, fn);
|
||||
this.playGate = next.catch(() => {});
|
||||
return next;
|
||||
}
|
||||
|
||||
getStatus(): BotStatus {
|
||||
return {
|
||||
id: this.id,
|
||||
|
||||
Reference in new issue
Block a user