Files
fpc-cron/docs/API.md

8.5 KiB

fpc-cron — API reference

Every callable the library exposes, with parameters, return values, and runnable examples. See architecture.md for the big picture and DEVELOPER_GUIDE.md for the consumer-oriented walkthrough.

Contents


Quick start

uses
  Classes, SysUtils, fpjson, DateUtils,
  log.types,
  database.types, database.pool,
  cron.types, cron.events, cron.runner;

var
  Pool: TDBPool;
  C:    TCron;
begin
  Pool := TDBPool.Create;
  Pool.Init(dbSQLite, '/tmp/cron.sqlite3');
  try
    C := TCron.Create(Pool, @MyHost.RunTask, nil, @MyHost.HandleLog);
    try
      C.OnTaskComplete := @MyHost.HandleTaskComplete;
      C.RegisterSystemTask('cleanup', @MyHost.RunCleanup);
      C.Start;
      ...
      C.Terminate;
    finally
      C.Free;
    end;
  finally
    Pool.Free;
  end;
end.

Types

cron.types:

type
  TCronTaskKind = (stkInterval, stkCron);

  TCronTask = record
    ID:               Integer;
    TaskName:         string;
    PluginName:       string;
    Description:      string;
    Category:         string;
    Kind:             TCronTaskKind;
    IntervalSeconds:  Integer;
    CronExpr:         string;
    Enabled:          Boolean;
    LastRun:          TDateTime;
    NextRun:          TDateTime;
    LastResult:       string;
    LastError:        string;
    RunCount:         Integer;
    FailCount:        Integer;
    UserModified:     Boolean;
    IsRunning:        Boolean;
  end;

  TRunTaskProc       = procedure(const APluginName, ATaskName: string) of object;
  TGetExtraTasksFunc = function: TJSONArray of object;
  TSystemTaskProc    = procedure(const ATaskName: string) of object;

The logger type is log.types.TLogProc, defined in fpc-log.

Events

cron.events defines the typed observer callbacks (same pattern as fpc-binkp's bp.events and fpc-comet's cm.events):

type
  TCronOnTaskStart      = procedure(const APluginName, ATaskName: string) of object;

  TCronOnTaskComplete   = procedure(const APluginName, ATaskName: string;
                                    ASuccess: Boolean; ADurationMs: Integer;
                                    const AError: string) of object;

  TCronOnTaskRegistered = procedure(const APluginName, ATaskName: string;
                                    AIntervalSeconds: Integer) of object;

  TCronOnPluginOrphaned = procedure(const APluginName: string) of object;

  TCronOnThreadStart    = procedure of object;

  TCronOnThreadStop     = procedure of object;

All callbacks are of object. nil is always valid (no-op).

Schema specs

function BuildSystemSchedulerSpec(const ANowExpr: string): TDBTable;
function BuildSchedulerLogSpec: TDBTable;

Return fpc-db TDBTable specs for the two runner-owned tables. Use these to declare schema independently of TCron.Create:

APool.DeclareTable(BuildSystemSchedulerSpec(APool.Dialect.NowExpr));
APool.DeclareTable(BuildSchedulerLogSpec);

The names mirror canonical Fastway fw_schema.pas's BuildSystemScheduler / BuildSchedulerLog so a Fastway database is reusable without migration.

TCron

TCron = class(TThread). Created suspended; caller calls .Start to begin the wake loop.

TCron.Create

constructor Create(APool: TDBPool;
                   ARunTask:        TRunTaskProc       = nil;
                   AGetExtraTasks:  TGetExtraTasksFunc = nil;
                   ALogger:         TLogProc           = nil);
  • APool — required. fpc-db pool the runner reads/writes its two tables on. Raises if nil.
  • ARunTask — invoked for every non-system task. nil means non-system tasks fail with 'No plugin task runner available'.
  • AGetExtraTasks — invoked at Create and on RefreshTasks to discover plugin tasks. nil means SyncPluginTasks is a no-op.
  • ALoggerlog.types.TLogProc. nil means silent.

Create calls Pool.DeclareTable for both schema specs, runs LoadTasksFromDB, and runs SyncPluginTasks. Returns a suspended thread — caller must call .Start.

TCron.Destroy

If the wake loop is running, Destroy calls Terminate, fires the stop event, and WaitFors the thread. Then frees the lock and the stop event. Safe to call from any thread.

TCron.RegisterSystemTask

procedure RegisterSystemTask(const AName: string; AProc: TSystemTaskProc);

Register a callback for a system/<AName> task. Calling twice with the same name replaces the previous entry. Replaces canonical Fastway's hardcoded case ATaskName of table.

If a plugin_name='system' task fires whose name isn't registered, the runner logs 'unknown system task: <name>' at llWarn and moves on.

TCron.RefreshTasks

procedure RefreshTasks;

Reload from the DB and re-run SyncPluginTasks. Use after inserting tasks externally, or after the supplier callback's return value has changed. Recomputes NextRun for every enabled task.

TCron.RunTaskNow

procedure RunTaskNow(ATaskID: Integer);

Synchronously run one task by row id. Updates LastRun, RunCount, FailCount, NextRun, writes a scheduler_log row, fires OnTaskStart + OnTaskComplete. Useful for "run now" buttons in admin UIs.

TCron.GetTasksJSON

function GetTasksJSON: TJSONArray;
function GetTaskJSON(ATaskID: Integer): TJSONObject;

Snapshot the in-memory task table. GetTaskJSON returns nil if the task ID isn't found. Caller owns the returned objects (must Free them). All last_run / next_run timestamps are formatted as 'yyyy-mm-dd hh:nn:ss' (UTC); null when unset.

TCron.UpdateTask

function UpdateTask(ATaskID: Integer; AUpdates: TJSONObject): Boolean;

Apply mutations to an existing task and persist to DB. Recognised keys in AUpdates:

  • enabled (Boolean)
  • schedule_type ('interval' or 'cron')
  • interval_seconds (Integer, must be > 0)
  • cron_expr (string)

Sets user_modified = 1 (which exempts the row from SyncPluginTasks orphan cleanup). Recomputes NextRun. Returns True if the task was found, False otherwise.

TCron.Running

property Running: Boolean read FRunning;

True between Execute start and stop.

TCron.OnTaskStart etc.

property OnTaskStart:      TCronOnTaskStart      ...;
property OnTaskComplete:   TCronOnTaskComplete   ...;
property OnTaskRegistered: TCronOnTaskRegistered ...;
property OnPluginOrphaned: TCronOnPluginOrphaned ...;
property OnThreadStart:    TCronOnThreadStart    ...;
property OnThreadStop:     TCronOnThreadStop     ...;

Wire by assignment (C.OnTaskStart := @Host.HandleStart). Each callback is invoked synchronously on the runner thread. nil (the default) means no-op.

TCron.ParseCronField

class function ParseCronField(const AField: string;
                              AMin, AMax: Integer): TBits;

Parse one cron field (*, */N, a,b,c, a-b, a-b/N, or a single literal). Returns a TBits of size AMax+1 with the matched values set. Caller frees the result.

Out-of-range literals are silently dropped.

TCron.MatchesCron

class function MatchesCron(const ACronExpr: string;
                           ATime: TDateTime): Boolean;

Test whether a 5-field cron expression matches the given TDateTime. Returns False if ACronExpr has fewer than 5 fields after splitting on whitespace.

ATime is treated as local time (canonical Fastway behaviour); the canonical's next_run math converts to UTC after the match.

Version constants

In cron.version:

const
  CRON_VERSION_MAJOR  = 0;
  CRON_VERSION_MINOR  = 1;
  CRON_VERSION_PATCH  = 0;
  CRON_VERSION_STRING = '0.1.0';

Bumped together with the git tag. Pin downstream consumers by tag, not commit hash.