Primordyx Framework Documentation

Cron
in package

Class Cron

For scheduling and executing background jobs in the Primordyx framework.

Jobs are stored as JSON and can include a cron-style schedule, named parameters, and an optional "once" flag. Supports file-based locking, memory/timing stats, and auto-unregistering run-once jobs after execution.

NOTE: Requires explicit initialization via Cron::init($basePath) before use.

Tags
since
1.0.0

Table of Contents

Properties

$basePath  : string|null
$initialized  : bool
$lockDir  : string
$registryFile  : string
$timestampsFile  : string

Methods

dispatch()  : void
Check all registered jobs and execute any that are due to run.
getBasePath()  : string|null
Get the current base path.
init()  : void
Initialize the Cron class with the base path for cron files.
isDue()  : bool
Check if a cron job is due to run based on its schedule expression and last execution time.
isInitialized()  : bool
Check if the Cron class has been initialized.
listJobs()  : array<string|int, mixed>
Get all registered cron jobs from the registry.
reset()  : void
Reset the initialization state (useful for testing).
schedule()  : void
Register or update a cron job for scheduled execution.
unschedule()  : bool
Remove a job from the schedule by ID.
ensureInitialized()  : void
Ensure the class is initialized.
match()  : bool
Check whether a single cron expression field matches a time value.

Properties

$basePath

protected static string|null $basePath = null

$initialized

protected static bool $initialized = false

$lockDir

protected static string $lockDir

$registryFile

protected static string $registryFile

$timestampsFile

protected static string $timestampsFile

Methods

dispatch()

Check all registered jobs and execute any that are due to run.

public static dispatch() : void

This is the main execution method that should be called regularly (typically from a system cron job every minute). It performs the following operations:

  1. Loads all registered jobs from the registry
  2. Checks each job's schedule against current time and last execution
  3. Uses file-based locking to prevent concurrent execution of the same job
  4. Executes due jobs with proper argument mapping and error handling
  5. Tracks execution time and memory usage for each job
  6. Auto-removes jobs marked with 'once' flag after successful execution
  7. Updates timestamps and registry files

Jobs are skipped if:

  • Not due according to cron schedule and last run time
  • Already locked by another process (with stale lock detection after 1 hour)
  • Missing required arguments or invalid callback

Events Fired:

  • 'cron.job.skipped' => ['jobId' => $id, 'reason' => 'locked', 'age' => $seconds]
  • 'cron.lock.stale' => ['jobId' => $id, 'age' => $seconds]
  • 'cron.job.starting' => ['jobId' => $id, 'job' => $jobConfig]
  • 'cron.job.completed' => ['jobId' => $id, 'elapsed' => $seconds, 'memoryPeak' => $bytes]
  • 'cron.job.removed' => ['jobId' => $id, 'reason' => 'one-time']
  • 'cron.job.failed' => ['jobId' => $id, 'error' => $message, 'exception' => $throwable]
Tags
throws
Exception

If the cron system is not initialized, or if critical file operations fail (registry/timestamp file writes)

example
// Typical usage in a system cron job that runs every minute:
// * * * * * /usr/bin/php /path/to/your/app/cron-runner.php

// In cron-runner.php:
Cron::init('/path/to/cron/storage');

// Register logging actions to handle cron events
EventManager::add_action('cron.job.starting', function($data) {
    Log::info("Running cron: {$data['jobId']}");
});

EventManager::add_action('cron.job.failed', function($data) {
    Log::error("Cron {$data['jobId']} failed: {$data['error']}");
});

EventManager::add_action('cron.job.completed', function($data) {
    Log::info("Cron {$data['jobId']} finished in {$data['elapsed']}s using {$data['memoryPeak']} memory");
});

Cron::dispatch(); // Checks and runs all due jobs
see
Cron::isDue()

For schedule evaluation logic

see
Cron::schedule()

For job registration

getBasePath()

Get the current base path.

public static getBasePath() : string|null
Return values
string|null

init()

Initialize the Cron class with the base path for cron files.

public static init(string $basePath) : void
Parameters
$basePath : string

The base directory where cron files will be stored

Tags
throws
InvalidArgumentException

If the path doesn't exist or isn't writable

isDue()

Check if a cron job is due to run based on its schedule expression and last execution time.

public static isDue(string $expr, int $now, int $last) : bool

Evaluates whether a job should execute by parsing the cron expression against the current time and ensuring it hasn't already run within the same minute. This prevents duplicate executions when dispatch() is called multiple times within a single minute.

The cron expression must be in standard 5-field format: "minute hour day month weekday" All fields must match the current time for the job to be considered due.

Minute-level granularity: Jobs will not run more than once per minute, even if the cron expression would otherwise allow it.

Parameters
$expr : string

Cron expression in 5-field format. Supported patterns:

  • '*' = matches any value
  • '/n' = matches every nth value (e.g., '/15' = every 15 units)
  • 'n' = matches exactly value n (e.g., '0' = exactly 0) Examples:
  • '0 * * * *' = every hour at minute 0
  • '*/5 * * * *' = every 5 minutes
  • '30 2 * * 1' = 2:30 AM every Monday
$now : int

Current Unix timestamp to evaluate against

$last : int

Unix timestamp of the job's last execution (0 if never run)

Tags
example
$now = time();
$lastRun = 1735689600; // Some previous timestamp

// Check if hourly job is due
if (Cron::isDue('0 * * * *', $now, $lastRun)) {
    echo "Hourly job should run now";
}

// Check if job should run every 15 minutes
if (Cron::isDue('*\/15 * * * *', $now, $lastRun)) {
    echo "15-minute job should run now";
}
Return values
bool

True if the job is due to run, false otherwise

isInitialized()

Check if the Cron class has been initialized.

public static isInitialized() : bool
Return values
bool

listJobs()

Get all registered cron jobs from the registry.

public static listJobs() : array<string|int, mixed>

Returns the complete job registry as an associative array where keys are job IDs and values contain the job configuration (schedule, callback, args, once flag).

Tags
throws
Exception

If the cron system is not initialized

example
$jobs = Cron::listJobs();
foreach ($jobs as $id => $config) {
    echo "Job: $id runs {$config['schedule']} calling {$config['callback']}\n";
}
Return values
array<string|int, mixed>

Associative array of all registered jobs. Returns empty array if no jobs are registered or registry file doesn't exist. Structure: [ 'job-id' => [ 'schedule' => '0 * * * *', // Cron expression 'callback' => 'ClassName::method', // Method to call 'args' => ['key' => 'value'], // Named arguments 'once' => false // Run-once flag ], // ... more jobs ]

reset()

Reset the initialization state (useful for testing).

public static reset() : void

schedule()

Register or update a cron job for scheduled execution.

public static schedule(string $expression, string $id, string $classMethod[, array<string|int, mixed> $args = [] ][, bool $once = false ]) : void

Creates a new cron job or updates an existing one with the same ID. Jobs are persisted to the registry file and will be checked for execution during each dispatch() call.

Parameters
$expression : string

Cron expression in standard 5-field format: 'minute hour day month weekday' Supports basic patterns:

  • '*' = any value
  • '/n' = every n units (e.g., '/15' = every 15 minutes)
  • specific numbers (e.g., '0' = exactly at minute 0) Examples: '0 * * * ' (hourly), '/5 * * * *' (every 5 min), '0 0 * * 0' (weekly)
$id : string

Unique identifier for this job. If a job with this ID already exists, it will be completely replaced with the new configuration.

$classMethod : string

The callback in 'ClassName::methodName' format. The class will be auto-loaded from the cron base path if not already loaded.

$args : array<string|int, mixed> = []

Named parameters to pass to the method. Keys should match the method's parameter names. Missing args will use defaults if available, or throw an exception if required. Example: ['userId' => 123, 'action' => 'cleanup']

$once : bool = false

If true, the job will automatically be removed from the registry after successful execution (run-once job). Defaults to false.

Tags
throws
InvalidArgumentException

If $classMethod is not in 'Class::method' format

throws
Exception

If the cron system is not initialized

example
// Schedule a daily cleanup at midnight
Cron::schedule('0 0 * * *', 'daily-cleanup', 'CleanupTasks::purgeOldLogs');

// Schedule every 10 minutes with named arguments
Cron::schedule('*\/10 * * * *', 'user-sync', 'UserSync::syncBatch', ['batchSize' => 100]);

// One-time job to run at next 2 AM
Cron::schedule('0 2 * * *', 'migration-task', 'Migration::runV2Migration', [], true);

unschedule()

Remove a job from the schedule by ID.

public static unschedule(string $id) : bool

Removes the specified job from the registry file if it exists. Fires a 'cron.job.unscheduled' event upon successful removal.

Parameters
$id : string

The unique identifier of the job to remove

Tags
throws
Exception

If the cron system is not initialized

example
if (Cron::unschedule('daily-cleanup')) {
    echo "Job removed successfully";
} else {
    echo "Job not found";
}
Return values
bool

True if the job was found and removed, false if the job ID doesn't exist

ensureInitialized()

Ensure the class is initialized.

protected static ensureInitialized() : void
Tags
throws
Exception

If not initialized

match()

Check whether a single cron expression field matches a time value.

protected static match(string $expr, int $value) : bool

This is a helper method used by isDue() to evaluate individual fields of a cron expression against their corresponding time values. Handles the three supported cron field patterns.

Supported patterns:

  • '*' = wildcard, matches any value
  • '/n' = step values, matches every nth occurrence (e.g., '/5' matches 0,5,10,15...)
  • 'n' = exact match, matches only the specific numeric value
Parameters
$expr : string

The cron field expression to evaluate (e.g., '', '15', '/5')

$value : int

The actual time value to check against (e.g., current minute, hour, etc.)

Tags
example
// Wildcard always matches
Cron::match('*', 25);     // returns true
Cron::match('*', 0);      // returns true

// Exact matches
Cron::match('15', 15);    // returns true
Cron::match('15', 30);    // returns false

// Step values
Cron::match('*\/5', 0);   // returns true (0 % 5 === 0)
Cron::match('*\/5', 15);  // returns true (15 % 5 === 0)
Cron::match('*\/5', 7);   // returns false (7 % 5 !== 0)
Return values
bool

True if the expression matches the value, false otherwise


        
On this page

Search results