Skip to content

refactor: extract shared IntervalScheduler base class (#1694) - #1752

Merged
LucasSantana-Dev merged 8 commits into
mainfrom
fix/1694-interval-scheduler-extraction
Jul 10, 2026
Merged

LucasSantana-Dev merged 8 commits into
mainfrom
fix/1694-interval-scheduler-extraction

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Jul 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

Extract the common start/stop/tick scaffold from BirthdayScheduler, ReminderScheduler, and GiveawayScheduler into a reusable IntervalScheduler base class that manages:

  • Timer and client lifecycle (timer, client fields)
  • Concurrent tick prevention (tickInProgress guard)
  • Standard start/stop methods
  • Template-method tick() with error handling

Subclasses implement execute() for domain-specific logic and override onStart() for custom initialization (e.g., running tick immediately on startup for birthday/reminder schedulers).

Resolves code duplication and allows removal of both reminderScheduler and giveawayScheduler from sonar-project.properties cpd.exclusions.

Changes

  • New: IntervalScheduler base class with protected lifecycle methods
  • Refactored: BirthdayScheduler, ReminderScheduler, GiveawayScheduler to extend the base class
  • Updated: sonar-project.properties to remove duplication exclusions for reminder and giveaway schedulers

Test Plan

  • Full bot test suite passes (all 3 schedulers' tests remain unchanged)
  • Type checking passes
  • Lint checks pass
  • Sonar duplication gate passes (previously excluded schedulers no longer flagged as duplicates)

Closes #1694


Summary by cubic

Refactored the birthday, reminder, and giveaway schedulers to share a new IntervalScheduler base, removing duplicated lifecycle code and standardizing error handling. Re-enabled Sonar CPD checks by removing scheduler exclusions (closes #1694).

  • Refactors

    • Added IntervalScheduler with start/stop, concurrency guard, and centralized error handling.
    • Schedulers now use onStart() for startup work and execute() for periodic tasks; birthday/reminder run an immediate tick on start.
    • Removed packages/bot/src/utils/general/reminderScheduler.ts and .../giveawayScheduler.ts from sonar.cpd.exclusions.
  • Bug Fixes

    • Removed stray closing braces causing parse errors.
    • Dedented execute() bodies after refactor.
    • Dropped unused Client imports.

Written for commit 9e0c2ab. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Refactor
    • Standardized birthday, giveaway, and reminder scheduling on a shared interval-based scheduler.
    • Prevented overlapping scheduler runs and added consistent error handling.
    • Preserved existing birthday, giveaway, and reminder processing behavior.
    • Improved scheduler startup logging and testability.
  • Chores
    • Updated code-quality analysis settings to include scheduler modules.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a shared IntervalScheduler base class and refactors birthday, giveaway, and reminder schedulers to implement its lifecycle hooks. Removes duplicated timer and concurrency code and removes the migrated schedulers from Sonar duplication exclusions.

Changes

Scheduler lifecycle refactor

Layer / File(s) Summary
Shared interval lifecycle
packages/bot/src/utils/general/IntervalScheduler.ts
Adds centralized client initialization, interval creation and cleanup, tick concurrency protection, subclass execution hooks, and default error logging.
Scheduler hook migrations
packages/bot/src/utils/general/birthdayScheduler.ts, packages/bot/src/utils/general/giveawayScheduler.ts, packages/bot/src/utils/general/reminderScheduler.ts
Migrates each scheduler to IntervalScheduler, preserving birthday reconciliation, giveaway processing, and per-reminder delivery handling through onStart() and execute().
Duplication configuration update
sonar-project.properties
Removes the birthday-related scheduler exclusions for reminder and giveaway files from sonar.cpd.exclusions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • LucasSantana-Dev/Lucky#1690: Refactors the giveaway scheduler lifecycle and is directly connected to the scheduler startup and shutdown changes.

Suggested labels: shared

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The refactor matches #1694 by centralizing the interval lifecycle and removing the CPD exclusions for reminder and giveaway schedulers.
Out of Scope Changes check ✅ Passed No unrelated changes are evident; the sonar-project.properties update directly supports the duplication cleanup requested by the issue.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main refactor: extracting a shared IntervalScheduler base class.
✨ 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/1694-interval-scheduler-extraction

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions

github-actions Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Warnings
⚠️

No test changes despite 4 source files modified (159 source lines added). If this is intentional (e.g. refactor, build config), reply explaining why.

Generated by 🚫 dangerJS against 9e0c2ab

Extract the common start/stop/tick scaffold from BirthdayScheduler,
ReminderScheduler, and GiveawayScheduler into a reusable IntervalScheduler
base class. This eliminates lifecycle duplication and allows removal of both
reminderScheduler and giveawayScheduler from cpd.exclusions, as the code
duplication is now resolved.

The base class manages:
- timer and client lifecycle
- tickInProgress guard for concurrent execution prevention
- start/stop methods for lifecycle management
- tick() method with error handling

Subclasses override execute() for domain-specific logic and onStart() for
custom initialization (e.g., running tick immediately on startup).

Fixes #1694
LucasSantana-Dev and others added 2 commits July 9, 2026 14:58
IntervalScheduler extraction left an extra closing brace in
reminderScheduler.ts and birthdayScheduler.ts, closing the class body
before deliverReminder()/reconcileGuildsWithoutMatches() etc — Jest
failed to parse both files (SyntaxError). Also dedents the
over-indented execute() bodies (leftover from removing the old
while-loop wrapper) and drops the now-unused Client import (client
access moved to the IntervalScheduler base class).
@github-actions github-actions Bot added size/l and removed size/m labels Jul 9, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 3 files (changes from recent commits).

Requires human review: Refactors scheduler lifecycle into a base class, which is high-impact code reorganization that could affect timing and concurrency.

Re-trigger cubic

@LucasSantana-Dev
LucasSantana-Dev enabled auto-merge (squash) July 9, 2026 18:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/bot/src/utils/general/giveawayScheduler.ts (1)

11-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused clock injection

GiveawayScheduler never reads this.clock, so the constructor option has no effect. Remove the field/option, or thread it into execute() if time-based behavior is planned.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bot/src/utils/general/giveawayScheduler.ts` around lines 11 - 18,
Remove the unused clock field and clock constructor option from
GiveawayScheduler; keep the constructor focused on tickIntervalMs unless
execute() is updated to use the injected clock.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/bot/src/utils/general/giveawayScheduler.ts`:
- Around line 11-18: Remove the unused clock field and clock constructor option
from GiveawayScheduler; keep the constructor focused on tickIntervalMs unless
execute() is updated to use the injected clock.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 33b59243-e654-4438-96ad-220cf6525498

📥 Commits

Reviewing files that changed from the base of the PR and between a59db7b and a7e85aa.

📒 Files selected for processing (5)
  • packages/bot/src/utils/general/IntervalScheduler.ts
  • packages/bot/src/utils/general/birthdayScheduler.ts
  • packages/bot/src/utils/general/giveawayScheduler.ts
  • packages/bot/src/utils/general/reminderScheduler.ts
  • sonar-project.properties

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 968bef4 into main Jul 10, 2026
42 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/1694-interval-scheduler-extraction branch July 10, 2026 03:09
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.

tech-debt: extract shared IntervalScheduler base (birthday/reminder/giveaway scaffold)

1 participant