Scheduler trait¶
Barberklingen\BasePlugin\Traits\Scheduler
Wraps the Action Scheduler library to provide recurring background jobs with a distributed process lock.
Usage¶
use Barberklingen\BasePlugin\Traits\Scheduler;
class MyBackgroundJob {
use Scheduler;
public function scheduler_name(): string {
return 'my-plugin/my-background-job';
}
public function scheduler_interval(): int {
return HOUR_IN_SECONDS; // run every hour
}
public function scheduler_logic(): void {
// Your business logic here.
// Only one instance runs at a time — the lock is held for up to
// get_process_lock_in_minutes() (default: 5).
}
}
MyBackgroundJob::get_instance();
How the lock works¶
The lock is stored in wp_options with autoload = no to prevent WordPress from loading it into the object cache on boot. The raw value is read directly from the database ($wpdb) to bypass Redis or other persistent object caches — this prevents a stale cache entry from making the lock appear permanently active.
Lock key: {scheduler_name}_lock
Lock value: Unix timestamp (when the lock was set)
Lock TTL: get_process_lock_in_minutes() × MINUTE_IN_SECONDS (default: 5 min)
If a process fails before releasing the lock, the next run after the TTL expires will proceed normally.
Execution flow¶
sequenceDiagram
participant CJ as cron.org / Action Scheduler
participant S as Scheduler trait
participant DB as wp_options (bypasses object cache)
CJ->>S: system_cron_job_org action
S->>S: maybe_start_scheduler()
note over S: registers recurring AS action if not already scheduled
CJ->>S: {scheduler_name} action (fired by Action Scheduler)
S->>DB: read lock directly (no cache)
alt lock free or expired
S->>DB: write lock (timestamp)
S->>S: scheduler_logic()
S->>DB: delete lock + clear cache
else already running
S-->>CJ: SchedulerAlreadyRunningException (NOOP)
end Configuration¶
| Method | Default | Description |
|---|---|---|
scheduler_name() | (required) | Action Scheduler action name |
scheduler_interval() | (required) | Interval in seconds |
scheduler_logic() | (required) | Business logic |
get_process_lock_in_minutes() | 5 | Override to allow longer jobs |
is_multiple_crons_allowed() | false | Set true to disable the lock |
Checking the next run¶
$timestamp = MyBackgroundJob::get_instance()->next_event_timestamp();
// returns false if not scheduled
Registering via cron.org¶
The system_cron_job_org WordPress action is fired by the CronEndpoint module when cron.org calls the wp-admin/admin-ajax.php?action=system_cron_job_org endpoint. The Scheduler trait hooks into this action to call maybe_start_scheduler(), ensuring the Action Scheduler recurring action is registered on the first run.