February 19th, 2026
The Native Scheduler is Alive: Self-Chaining Alarms Today we built the core native scheduling engine — a Kotlin module that reads task recurrence rules from the local SQLite database and creates self-perpetuating alarm chains entirely on the native side.SchedulerModule (New Expo Module)
Commit:feat(native): add SchedulerModule with self-chaining alarm system
Located at modules/scheduler-module/, this is the heart of our offline alarm system.
How It Works
- Reads task data from local SQLite (
commit.db). - Parses recurrence rules (type,
days_of_week,time_windows). - Calculates the next time slot using
findNextTimeSlot(). - Schedules an action at the computed time via
Handler.postDelayed(). - Self-chains: When the action fires, it automatically calculates and schedules the NEXT occurrence. The chain continues indefinitely.
Architecture
- Per-task chains tracked via
ConcurrentHashMap<convexId, Runnable>. - One-time tasks end after first fire.
- Recurring tasks chain forever until cancelled.
API
Frontend Integration
Bug Fixes
Three subtle bugs were discovered and resolved during implementation:1. DB Path Mismatch
- Problem: Module was using
getDatabasePath()which returned the wrong directory. - Fix: expo-sqlite stores databases at
filesDir/SQLite/, not the default Android DB path.
2. Chain Not Continuing
- Problem:
findNextTimeSlot()kept returning the same window becauseendSecs > currentSecswas true for the currently active window. - Fix: Added an
afterMsparameter to skip past windows that have already been processed.
3. Adjacent Windows Skipped
- Problem: A window starting at exactly the previous window’s end time was being excluded.
- Fix: Changed
<=to<in the comparison so the boundary case is correctly included.
Legacy Cleanup
- Removed: Old plugin-based
withAlarmModule/approach. - Removed: Manual
AlarmPackageregistration fromMainApplication.kt. - Refactored:
AlarmModulenow uses the modern Expo Modules Kotlin DSL.