perf: use channel.purge() instead of per-message delete loops (#93) #108

Merged
cal merged 1 commits from ai/major-domo-v2#93 into next-release 2026-03-20 17:44:30 +00:00
Collaborator

Closes #93

Summary

Replace sequential message.delete() loops with channel.purge() bulk delete in three locations:

  • commands/admin/management.pyadmin_clear_scorecards: was up to 100 individual API calls; now 1
  • tasks/live_scorebug_tracker.py_post_scorebugs_to_channel: was up to 25 individual deletes on every 3-minute cycle; now 1
  • tasks/live_scorebug_tracker.py_clear_live_scores_channel: same as above

channel.purge() uses Discord's bulk delete endpoint which handles up to 100 messages per request. Messages in the scorebug channel and live-scores channel are always recent (seconds to minutes old), well within the 14-day bulk delete limit.

Test results

935 passed, 2 skipped (18 pre-existing failures from unrelated working-tree modifications — confirmed baseline, not introduced by this PR)

Closes #93 ## Summary Replace sequential `message.delete()` loops with `channel.purge()` bulk delete in three locations: - **`commands/admin/management.py`** — `admin_clear_scorecards`: was up to 100 individual API calls; now 1 - **`tasks/live_scorebug_tracker.py`** — `_post_scorebugs_to_channel`: was up to 25 individual deletes on every 3-minute cycle; now 1 - **`tasks/live_scorebug_tracker.py`** — `_clear_live_scores_channel`: same as above `channel.purge()` uses Discord's bulk delete endpoint which handles up to 100 messages per request. Messages in the scorebug channel and live-scores channel are always recent (seconds to minutes old), well within the 14-day bulk delete limit. ## Test results 935 passed, 2 skipped (18 pre-existing failures from unrelated working-tree modifications — confirmed baseline, not introduced by this PR)
Claude added 1 commit 2026-03-20 17:02:42 +00:00
perf: use channel.purge() instead of per-message delete loops (#93)
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m16s
8878ce85f7
Closes #93

Replace sequential message.delete() loops with channel.purge() bulk
delete in three locations:
- commands/admin/management.py: admin_clear_scorecards (up to 100 msgs)
- tasks/live_scorebug_tracker.py: _post_scorebugs_to_channel (25 msgs)
- tasks/live_scorebug_tracker.py: _clear_live_scores_channel (25 msgs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude added the
ai-reviewing
label 2026-03-20 17:15:49 +00:00
Claude reviewed 2026-03-20 17:17:17 +00:00
Claude left a comment
Author
Collaborator

Review: perf: use channel.purge() instead of per-message delete loops

Verdict: APPROVED (posted as COMMENT — Gitea blocks self-approval)


What was reviewed

Three history() + per-message delete() loops replaced with channel.purge() in:

  • commands/admin/management.pyadmin_clear_scorecards (limit=100)
  • tasks/live_scorebug_tracker.py_post_scorebugs_to_channel (limit=25)
  • tasks/live_scorebug_tracker.py_clear_live_scores_channel (limit=25)

Plus a cosmetic trailing-comma reformat on the read_scorebug_data call (no behavioral effect).


Findings

Correctness — no issues.

All three changes are semantically equivalent on the success path. Specific checks:

  • management.py NotFound handling: The old inner try/except discord.NotFound: pass is removed. This is correct — channel.purge() handles 404s internally per message (discord.py discards not-found messages during bulk delete). No regression.
  • Return value: deleted_messages = await live_scores_channel.purge(...)len(deleted_messages) correctly maintains the deleted_count used in the success embed. The two tracker methods discard the return value, which is correct (they logged a fixed string, not a count).
  • Error handling preserved: All three sites have outer except discord.Forbidden + except Exception wrappers that survive unchanged. Permissions failures produce user-facing messages in management.py and structured logs in the tracker.
  • 14-day bulk delete limit: Not a concern here. The live-scores channel is cleared every 3 minutes; the admin command targets the same channel. No message is anywhere near 14 days old.

Minor note — permission dependency shift (no action required, informational):

channel.purge() internally calls channel.delete_messages() (the Discord bulk-delete endpoint), which requires MANAGE_MESSAGES. The old per-message message.delete() on the bot's own messages does not require MANAGE_MESSAGES — only message ownership. In practice the bot certainly has MANAGE_MESSAGES in a channel it manages, so this is a very low-risk behavioural note. If it ever became a problem, it would fail with Forbidden (already caught).


Test results

935 passed, 2 skipped, 18 pre-existing failures (unrelated working-tree modifications — confirmed baseline, not introduced by this PR).


Mergeable: true. No blocking issues.

## Review: perf: use channel.purge() instead of per-message delete loops **Verdict: APPROVED** (posted as COMMENT — Gitea blocks self-approval) --- ### What was reviewed Three `history()` + per-message `delete()` loops replaced with `channel.purge()` in: - `commands/admin/management.py` — `admin_clear_scorecards` (limit=100) - `tasks/live_scorebug_tracker.py` — `_post_scorebugs_to_channel` (limit=25) - `tasks/live_scorebug_tracker.py` — `_clear_live_scores_channel` (limit=25) Plus a cosmetic trailing-comma reformat on the `read_scorebug_data` call (no behavioral effect). --- ### Findings **Correctness — no issues.** All three changes are semantically equivalent on the success path. Specific checks: - **`management.py` `NotFound` handling**: The old inner `try/except discord.NotFound: pass` is removed. This is correct — `channel.purge()` handles 404s internally per message (discord.py discards not-found messages during bulk delete). No regression. - **Return value**: `deleted_messages = await live_scores_channel.purge(...)` → `len(deleted_messages)` correctly maintains the `deleted_count` used in the success embed. The two tracker methods discard the return value, which is correct (they logged a fixed string, not a count). - **Error handling preserved**: All three sites have outer `except discord.Forbidden` + `except Exception` wrappers that survive unchanged. Permissions failures produce user-facing messages in `management.py` and structured logs in the tracker. - **14-day bulk delete limit**: Not a concern here. The live-scores channel is cleared every 3 minutes; the admin command targets the same channel. No message is anywhere near 14 days old. **Minor note — permission dependency shift** (no action required, informational): `channel.purge()` internally calls `channel.delete_messages()` (the Discord bulk-delete endpoint), which requires `MANAGE_MESSAGES`. The old per-message `message.delete()` on the bot's *own* messages does not require `MANAGE_MESSAGES` — only message ownership. In practice the bot certainly has `MANAGE_MESSAGES` in a channel it manages, so this is a very low-risk behavioural note. If it ever became a problem, it would fail with `Forbidden` (already caught). --- ### Test results 935 passed, 2 skipped, 18 pre-existing failures (unrelated working-tree modifications — confirmed baseline, not introduced by this PR). --- **Mergeable: true. No blocking issues.**
cal changed target branch from main to next-release 2026-03-20 17:43:52 +00:00
cal merged commit f0934937cb into next-release 2026-03-20 17:44:30 +00:00
cal deleted branch ai/major-domo-v2#93 2026-03-20 17:44:30 +00:00
cal removed the
ai-reviewing
label 2026-03-23 15:32:37 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/major-domo-v2#108
No description provided.