Skip to content

Commit

Permalink
add cron monitor support (runs background processes more quickly as n…
Browse files Browse the repository at this point in the history
…eeded)
  • Loading branch information
brookgagnon committed Sep 12, 2024
1 parent cce768d commit c197aa8
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 84 deletions.
1 change: 0 additions & 1 deletion .phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<file>api.php</file>
<file>components.php</file>
<file>config.sample.php</file>
<file>cron.php</file>
<file>index.php</file>
<file>remote.php</file>
<file>strings.php</file>
Expand Down
4 changes: 2 additions & 2 deletions classes/cron/extractthumbnails.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class ExtractThumbnails extends Cron
{
public function interval(): int
{
return 60;
return 1;
}

public function run(): bool
Expand Down Expand Up @@ -57,7 +57,7 @@ public function run(): bool
}
}

return false;
return true;
}

private function runVideo($item, $input_file, $output_file): bool
Expand Down
78 changes: 0 additions & 78 deletions cron.php

This file was deleted.

110 changes: 110 additions & 0 deletions tools/cli/commands/cron.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace ob\tools\cli;

if (!defined('OB_CLI')) {
die('Command line access only.');
}

require_once('components.php');

$db = \OBFDB::get_instance();

// lock is aquired right before running task, and released right after.
$lock = new \OBFLock('core-cron');

// require cron files
// TODO add support for module cron classes (last run tracked in db as cron-modulename-classname).
$jobs = [];
require_once('classes/base/cron.php');
foreach (glob('classes/cron/*.php') as $file) {
require_once($file);
$class = '\OB\Classes\Cron\\' . basename($file, '.php');
$jobs[] = new $class();
}

// check our jobs to see what needs to be run
$jobs_to_run = [];
foreach ($jobs as $index => $job) {
// reliable way to get the class name without namespace
$classReflection = new \ReflectionClass($job);
$className = strtolower($classReflection->getShortName());

// get our last run time
$db->where('name', 'cron-core-' . $className);
$lastRun = $db->get_one('settings');

// if no last run time, set nextRun to zero
if (!$lastRun) {
$nextRun = 0;
} else {
$nextRun = $lastRun['value'] + $job->interval();
}
$jobs_to_run[$index] = ['nextRun' => $nextRun, 'className' => $className];
}

$run_jobs = function () use ($jobs, &$jobs_to_run, $db, $lock) {
// loop through jobs and check interval against last run. run if needed.
foreach ($jobs_to_run as $index => $job_to_run) {
// if not time to run, skip
if ($job_to_run['nextRun'] > time()) {
continue;
}

// aquire lock (or exit)
$lock_aquired = $lock->acquire();
if (!$lock_aquired) {
echo 'Unable to get cron lock. Is another monitor or job already running?' . PHP_EOL;
exit(1);
}

// get the job
$job = $jobs[$index];

// run job
$status = $job->run();

// if successful, update last run time for this job and main, as well as update our next run time locally
if ($status) {
// update last run time for this job
if ($job_to_run['nextRun'] > 0) {
// has previous run, update time.
$db->where('name', 'cron-core-' . $job_to_run['className']);
$db->update('settings', ['value' => time()]);
} else {
// first time running, insert time.
$db->insert('settings', ['name' => 'cron-core-' . $job_to_run['className'], 'value' => time()]);
}

// update next run time in our local variable
$jobs_to_run[$index]['nextRun'] = time() + $job->interval();

// update our main cron_last_run time
$db->where('name', 'cron_last_run');
$cron_last_run = $db->get_one('settings');
if (!$cron_last_run) {
$db->insert('settings', ['name' => 'cron_last_run', 'value' => time()]);
} else {
$db->where('name', 'cron_last_run');
$db->update('settings', ['value' => time()]);
}

// update $jobs_to_run with next time
$jobs_to_run[$index]['nextRun'] = time() + $job->interval();
}

// release our lock
$lock->release();
}
};

if ($subcommand === 'monitor') {
// monitor mode
echo 'cron monitor started' . PHP_EOL;
while (true) {
$run_jobs();
sleep(1);
}
} else {
$run_jobs();
}
7 changes: 4 additions & 3 deletions tools/cli/ob.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public function help()

echo Helpers::table(spacing: 5, rows: [
['check', 'check installation for errors'],
['cron run', 'run scheduled tasks'],
['cron run', 'run scheduled tasks once'],
['cron monitor', 'monitor and run cron tasks as needed'],
['updates list all', 'list all available updates'],
['updates list core', 'list core ob updates'],
['updates list module <name>', 'list updates for specified module'],
Expand All @@ -83,8 +84,8 @@ public function check()
public function cron()
{
global $subcommand;
if ($subcommand == 'run') {
require('cron.php');
if ($subcommand == 'run' || $subcommand == 'monitor') {
require(__DIR__ . '/commands/cron.php');
} else {
$this->help();
}
Expand Down

0 comments on commit c197aa8

Please sign in to comment.