OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

scheduler.php

2 KB
<?php
/**
 * Unified cron scheduler entry point.
 *
 * Replaces the per-job crontab entries with a single line:
 *
 *   * * * * *  /usr/bin/php /pfad/zu/bin/scheduler.php >> /pfad/zu/storage/logs/scheduler.log 2>&1
 *
 * On every minute-tick it picks all tasks from `cron_tasks` whose
 * `next_run_at` is due and either runs them inline or detaches a background
 * worker (bin/run-task.php). Per-task admin-tunable schedule lives in the
 * cron_tasks table; the corresponding admin UI is at /admin/cronjobs.
 */

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../bootstrap.php';

use OpenNIT\Cron\BackgroundDispatcher;
use OpenNIT\Cron\Bootstrap;
use OpenNIT\Cron\Scheduler;
use OpenNIT\Cron\TaskRegistry;

$rootDir = dirname(__DIR__);

try {
    $context = Bootstrap::init($rootDir);
} catch (\Throwable $e) {
    fwrite(STDERR, '[scheduler] Bootstrap failed: ' . $e->getMessage() . PHP_EOL);
    exit(1);
}

$lockDir = $rootDir . '/storage/locks';
$logDir  = $rootDir . '/storage/logs';
if (!is_dir($logDir)) {
    @mkdir($logDir, 0775, true);
}

$registry   = new TaskRegistry();
$dispatcher = new BackgroundDispatcher(
    phpBinary:    PHP_BINARY,
    workerScript: __DIR__ . '/run-task.php',
    logFile:      $logDir . '/scheduler.log',
);

$scheduler = new Scheduler($context->db, $context, $registry, $dispatcher, $lockDir);

$stats = $scheduler->tick();

// Single-line summary so cron mails / log tails stay readable.
$ts = date('Y-m-d H:i:s');
printf(
    "[%s] tick: dispatched=%d inline=%d background=%d skipped=%d errors=%d%s",
    $ts,
    $stats['dispatched'],
    $stats['inline'],
    $stats['background'],
    $stats['skipped'],
    $stats['errors'],
    PHP_EOL
);

exit($stats['errors'] > 0 ? 1 : 0);