Skip to content

fix(bot): serialize autoplay replenish per guild, write redis on add - #565

Merged
LucasSantana-Dev merged 1 commit into
mainfrom
fix/autoplay-mutex-and-dedup
Apr 11, 2026
Merged

LucasSantana-Dev merged 1 commit into
mainfrom
fix/autoplay-mutex-and-dedup

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Apr 11, 2026 •

Copy link
Copy Markdown
Owner

Root Causes Fixed

Full analysis is in .claude/plans/autoplay-dedup-fix-2026-04-11.md.

1. Race condition (CRITICAL) — per-guild mutex

replenishQueue was called concurrently from playerStart, playerFinish, and playerSkip. Each call built its own local excludedUrls/excludedKeys sets at call time. If two calls overlapped by even a few milliseconds, both would see the same exclusion sets and independently select the same track.

Fix: Module-level replenishLocks: Map<string, Promise<void>>. Each replenishQueue call for a guild chains onto the previous call's promise, ensuring serialization.

2. Just-added tracks not in Redis for concurrent calls

Previously, autoplay tracks were only written to Redis history when they finished playing. The concurrent call from the next event would not find them in Redis exclusions.

Fix: addSelectedTracks now immediately writes each added track to Redis history (fire-and-forget void). The next replenish call (milliseconds later) finds them in Redis.

3. History lookback too short

Changed getTrackHistory(guild.id, 20) → getTrackHistory(guild.id, 50). Covers ~3h sessions.

Observability

  • warnLog when Redis history is empty (potential Redis issue)
  • debugLog with exclusion set sizes after build (visible in debug mode)

1905 tests, 0 failures.

Summary by CodeRabbit

  • Improvements
    • Increased the historical track pool for autoplay selection from 20 to 50 entries, enhancing song variety and reducing repeat plays
    • Improved queue synchronization to prevent processing conflicts during concurrent operations

@vercel

vercel Bot commented Apr 11, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment Apr 11, 2026 7:38pm

Request Review

@coderabbitai

coderabbitai Bot commented Apr 11, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Test mocks extended with warnLog and trackHistoryService.addTrack stubs. Implementation refactors replenishQueue to a non-async synchronous wrapper enforcing per-guild serialization via in-memory Map-based mutex, delegates actual work to internal _replenishQueue, increases track history read size to 50, adds immediate history writes when selecting autoplay tracks, and expands exclusion-set construction to include title-only keys.

Changes

Cohort / File(s) Summary
Test Mocks
packages/bot/src/utils/music/queueManipulation.spec.ts
Extended Jest mocks to include warnLog: jest.fn() stub and trackHistoryService.addTrack mocked to return resolved promise.
Queue Replenishment Logic
packages/bot/src/utils/music/queueManipulation.ts
Converted replenishQueue from async function to synchronous wrapper implementing per-guild mutex via Map<string, Promise<void>>, delegating to new internal _replenishQueue async function. Increased persistent history read size from 20 to 50. Added warning when history empty. Expanded exclusion-set construction to include YouTube video IDs and normalized title-only keys. Added immediate trackHistoryService.addTrackToHistory writes during selected track addition.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

bot, size/l

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and specifically summarizes the two main changes: implementing per-guild serialization for autoplay replenish operations and writing Redis history immediately on track addition.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/autoplay-mutex-and-dedup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 6d42141 into main Apr 11, 2026
11 of 12 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/autoplay-mutex-and-dedup branch April 11, 2026 19:42

This branch was successfully deployed

1 active deployment
Preview — 70e34d9b Deployed Apr 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant