Wipes v0.1.0/v0.1.1 history. fpc-cron hadn't shipped to any external consumer yet; the rebuild against fpc-db v0.4.0 was inline development noise. This commit + tag is the clean public starting point. CRON_VERSION reset to 0.1.0. CHANGELOG rewritten as a single 0.1.0 entry covering the full library surface as it stands now.
5.6 KiB
5.6 KiB
Changelog
All notable changes to fpc-cron are recorded here. Every
release tag (vX.Y.Z) points at the commit that bumped
CRON_VERSION in src/cron.version.pas. Downstream consumers
should pin by tag, not commit hash.
Semver intent:
- major — breaks callers (API removal, signature change)
- minor — additive features
- patch — bug fixes, internal cleanups
0.1.0 — 2026-05-06
Initial public release. Cron + interval task runner extracted
from canonical Fastway TFWScheduler (fw_scheduler.pas,
1093 lines) per feedback_copy_dont_reinterpret.md. Cron
parser bodies are byte-identical to canonical after the
type-rename normalisation.
Added
cron.runner.TCron— task runner thread, public surface:Create(APool, ARunTask=nil, AGetExtraTasks=nil, ALogger=nil)— constructs in suspended state; declares schema, loads tasks, runsSyncPluginTasks.RegisterSystemTask(AName, AProc)— register a callback for asystem/<name>task (replaces canonical's hardcoded case-table).RefreshTasks/RunTaskNow(ATaskID).GetTasksJSON: TJSONArray/GetTaskJSON(ATaskID): TJSONObject.UpdateTask(ATaskID, AUpdates): Boolean— apply enabled / schedule_type / interval_seconds / cron_expr changes, persists to DB.Running: Boolean.class function ParseCronField(AField, AMin, AMax): TBitsclass function MatchesCron(ACronExpr, ATime): Boolean- Typed observer properties:
OnTaskStart/OnTaskComplete/OnTaskRegistered/OnPluginOrphaned/OnThreadStart/OnThreadStop.
cron.types—TCronTaskKind,TCronTask,TRunTaskProc,TGetExtraTasksFunc,TSystemTaskProc.cron.events— typed observer callback types (TCronOnTaskStart, ...) following the bp.events / cm.events pattern.cron.runner.BuildSystemSchedulerSpec(ANowExpr): TDBTableandBuildSchedulerLogSpec: TDBTable—database.TDBTablespecs mirroring canonical Fastwayfw_schema.pas'sBuildSystemScheduler/BuildSchedulerLog.cron.version—CRON_VERSIONsemver constants.
Adjustments from canonical (the only behaviour-preserving
changes)
| Canonical | fpc-cron |
|---|---|
TFWScheduler |
TCron |
TFWSchedulerTask |
TCronTask |
TFWSchedulerTaskKind |
TCronTaskKind |
TRunPluginTaskProc |
TRunTaskProc |
TGetPluginTasksFunc |
TGetExtraTasksFunc |
usesclause swaps: dropsfw_consts/fw_log/fw_config/fw_database/fw_plugin_api/fw_plugin_updates/fw_plugin_host/dbapi_consts/dbapi_dialect; addslog.types(fpc-log),database.dialect/database.schema/database.pool(fpc-db v0.1.0),cron.types/cron.events.- Global
DBreplaced withTDBPoolparameter onCreate. EventBus.Fire(...)calls replaced with typed observer callbacks (assignable as properties onTCron). Same per-library typed-callback pattern as fpc-binkp'sbp.eventsand fpc-comet'scm.events.fw_log.Log.X(...)calls routed through optionallog.types.TLogProccallback withCategory='cron'.DoWalCheckpointTruncate(SQLite + Fastway specific) and the hardcodedcase ATaskNamesystem-task table lifted out — consumers register their own system tasks viaRegisterSystemTask.- No global
Schedulersingleton — consumer creates own. ParseCronField/MatchesCronpromoted from private instance methods toclass functionfor testability; bodies byte-verbatim from canonical.
Behaviours preserved verbatim (per the COPY rule)
LoadTasksFromDB/SyncPluginTasks/UpdateTaskInDB/LogTaskRunhit the database directly.- 5-position cron parser (
*,*/N,a,b,c,a-b,a-b/N, literal). - Cron expressions in local time; UTC at storage time.
UTCNow = LocalTimeToUniversal(Now)for every persisted timestamp.- Schedule-miss-on-long-task: next firing is delay AFTER previous run returned.
- TThread + PRTLEvent + 1-second wake loop.
- Suspended-Create +
.Start. - SyncPluginTasks orphan cleanup.
- Event names through bus bridge:
'scheduler.task_start'and'scheduler.task_result'(canonical literals). - DB table names
system_schedulerandscheduler_logkept verbatim (Fastway database is reusable as-is).
Known issues inherited verbatim
MatchesCronallocates the fiveTBitsfield-bit-arrays before itstry/finally; ifParseCronFieldraises on field 2..5, earlierTBitsinstances leak. Negligible real-world impact.MatchesCroncallsDecodeDateFully(ATime, Mn, Hr, Dom, Dow)whose results are immediately overwritten by the next four calls. Cosmetic.
Tests
73 assertions across 23 scenarios:
tests/test_cron.pas— 37 pure-cron assertions.tests/test_runner.pas— 36 SQLite-backed end-to-end: Init, NextRun-recalc, RunTaskNow, SyncPluginTasks add + orphan, IntervalFires, SystemTaskFires, SystemTaskFailureRecorded, UpdateTask-disables, RefreshTasks, typed observer callbacks fire, cron task executes through runner, two runners on one pool (idempotent DeclareTable).
Examples
examples/interval_task.pas— 5-second interval task.examples/cron_task.pas— daily 3 AM cron task.
Build and test
bash build.sh # compile every src/*.pas
bash run_tests.sh # build + tests + examples
fpc.cfg provides multi-target FPC config.
Dependencies
- fpc-log v0.1.0 —
log.types.TLogProc - fpc-db v0.1.0 —
database.{dialect,schema,pool}