All notable changes to this project are documented in this file.
The format follows Keep a Changelog and the project adheres to Semantic Versioning.
- Compile-only
examples/v2_api_compilesketch to exercise the native v2 API surface in CI. - Lifecycle and overlap coverage in the Unity test sketch for skip, queue-one, allow-parallel, background no-
tick(), explicit shutdown, and v1 compatibility cleanup behavior. - Optional built-in
ESPWorkerasync backend selection throughSchedulerConfig. refreshAllSchedules()to recompute recurring jobs after wall-clock changes without touching one-shot UTC jobs.
- CI now runs on every branch push and is split into PlatformIO v2 API builds, PlatformIO example builds, PlatformIO device test sketch builds, Arduino CLI v2 API builds, and Arduino CLI example builds.
- Background command submission now treats a full control queue as
QueueFullimmediately instead of waiting for the control timeout window. SchedulerCorenow uses a scheduler-owned job id index, explicit pending-schedule bookkeeping, direct-indexed completion events, and heap-top validation instead of recovering hot-path state through whole-container scans.- Recurring schedules now auto-refresh on NTP sync and after local midnight; manual mode applies that refresh on the next
tick(), while background mode wakes immediately on sync and also wakes at the next local midnight boundary.
- Scheduler reschedule paths now clear
hasNextif a due-heap insertion fails, so jobs are retried on the next dispatch pass instead of getting stuck in a primed-but-undispatchable state. - PSRAM task-stack flags are now honored by the scheduler service task, worker-pool executor, and dedicated-task executor when the platform supports external task stacks.
- Background next-deadline lookup now purges stale heap entries lazily and returns the actual earliest valid due job without scanning the heap.
- Completion events now validate slot index, job id, and generation directly, which keeps stale completions from touching reused slots.
- Background command completion now snapshots abandoned ownership before signaling producers, which prevents a use-after-free race during background control command handoff.
- Recurring jobs that were queued before an NTP or DST change now recompute their next occurrence instead of dispatching against stale
nextRunUtctimestamps. - CI now pins PIOArduino Core to
v6.1.19and installs the ESP32 platform viapio pkg install, restoring PlatformIO compatibility with the currentplatform-espressif32package.
2.0.0 - 2026-03-27
- New
ESPSchedulerv2 API with explicitbegin()/end()lifecycle andSchedulerResult<T>return types. ScheduleSpec/ScheduleCalculatorsplit so schedule validation and next-occurrence math are independent from runtime state.SchedulerCorewith min-heap due tracking, centralized job ownership, generation counters, and explicit overlap handling.SchedulerMode::ManualandSchedulerMode::Background.DispatchPolicyandOverlapPolicy.- Built-in worker-pool executor, dedicated-task executor, and
ESPWorkerExecutorAdapter. - Background scheduler service with one scheduler task, command queue, and event queue.
- Job-id-based
getJobInfo()with runtime state fields for debugging. - New v2-native examples for manual mode, background worker pool,
ESPWorkeradapter, shutdown, and v1 compatibility. ESPSchedulerV1Compatwrapper for legacy code paths.
- Async scheduling no longer defaults to one FreeRTOS task per scheduled job.
- Background mode no longer requires
tick(). - Public docs now describe v2 as the primary API surface.
- Scheduler ownership and shutdown paths are centralized instead of being spread across per-job worker tasks.
- Async completion now flows back through the scheduler core, keeping reschedule decisions in one place.
- Clock validity guard: inline and worker jobs stay idle until the wall clock reaches a configurable minimum (default 2020-01-01 UTC) to prevent catch-up storms when SNTP sets time after boot.
std::functioncallback overloads foraddJob/addJobOnceUtcto allow capturing lambdas.std::function<void()>overloads foraddJob/addJobOnceUtcto allow no-arg lambdas.- Added focused recurring-pattern examples for every minute, every day, every hour, selected weekdays, and work-hour interval schedules.
deinit()plus destructor cleanup for deterministic job teardown, including worker task destruction.ESPSchedulerConfigwithusePSRAMBufferstoggle to route scheduler-owned dynamic buffers through ESPBufferManager (safe fallback to default heap when PSRAM is unavailable).- Additive constructor overloads that accept
ESPSchedulerConfigwhile preserving existing constructor signatures. isInitialized()lifecycle state onESPScheduler, including explicit teardown/re-init behavior afterdeinit().- Lifecycle Unity tests for teardown safety (
deinitbefore use, repeateddeinit, and re-init by scheduling again).