Add simple API and starter for cron jobs
parent
b18b960fb0
commit
a213a38b3c
|
@ -77,7 +77,8 @@ class Mcp implements ConnectionProvider
|
||||||
|
|
||||||
public function config($key): string|array|int
|
public function config($key): string|array|int
|
||||||
{
|
{
|
||||||
return $this->config[strtolower($key)];
|
$realKey = strtolower($key);
|
||||||
|
return isset($this->config[$realKey]) ? $this->config[$realKey] : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function csrfField(): string
|
public function csrfField(): string
|
||||||
|
|
|
@ -14,6 +14,7 @@ class MigrationManager
|
||||||
'CREATE TABLE IF NOT EXISTS `mcp_invites` (`InviteCode` CHAR(64) NOT NULL, PRIMARY KEY (`InviteCode`)) ENGINE InnoDB',
|
'CREATE TABLE IF NOT EXISTS `mcp_invites` (`InviteCode` CHAR(64) NOT NULL, PRIMARY KEY (`InviteCode`)) ENGINE InnoDB',
|
||||||
'CREATE TABLE IF NOT EXISTS `mcp_offlineim_send` (`id` int(6) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
'CREATE TABLE IF NOT EXISTS `mcp_offlineim_send` (`id` int(6) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci',
|
||||||
'CREATE TABLE IF NOT EXISTS `mcp_regions_info` (`regionID` CHAR(36) NOT NULL COLLATE utf8_unicode_ci, `RegionVersion` VARCHAR(128) NOT NULL DEFAULT "" COLLATE utf8_unicode_ci, `ProcMem` INT(11) NOT NULL, `Prims` INT(11) NOT NULL, `SimFPS` INT(11) NOT NULL, `PhyFPS` INT(11) NOT NULL, `OfflineTimer` INT(11) NOT NULL DEFAULT 0, PRIMARY KEY (`regionID`) USING BTREE) COLLATE=utf8_unicode_ci ENGINE=InnoDB',
|
'CREATE TABLE IF NOT EXISTS `mcp_regions_info` (`regionID` CHAR(36) NOT NULL COLLATE utf8_unicode_ci, `RegionVersion` VARCHAR(128) NOT NULL DEFAULT "" COLLATE utf8_unicode_ci, `ProcMem` INT(11) NOT NULL, `Prims` INT(11) NOT NULL, `SimFPS` INT(11) NOT NULL, `PhyFPS` INT(11) NOT NULL, `OfflineTimer` INT(11) NOT NULL DEFAULT 0, PRIMARY KEY (`regionID`) USING BTREE) COLLATE=utf8_unicode_ci ENGINE=InnoDB',
|
||||||
|
'CREATE TABLE IF NOT EXISTS `mcp_cron_runs` (`Name` VARCHAR(50) NOT NULL, `LastRun` INT(11) UNSIGNED NOT NULL, PRIMARY KEY(`Name`)) ENGINE InnoDB',
|
||||||
'CREATE TRIGGER IF NOT EXISTS del_id_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_user_identities WHERE mcp_user_identities.PrincipalID = OLD.PrincipalID OR mcp_user_identities.IdentityID = OLD.PrincipalID',
|
'CREATE TRIGGER IF NOT EXISTS del_id_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_user_identities WHERE mcp_user_identities.PrincipalID = OLD.PrincipalID OR mcp_user_identities.IdentityID = OLD.PrincipalID',
|
||||||
'CREATE TRIGGER IF NOT EXISTS del_pwres_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_password_reset WHERE mcp_password_reset.PrincipalID = OLD.PrincipalID'
|
'CREATE TRIGGER IF NOT EXISTS del_pwres_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_password_reset WHERE mcp_password_reset.PrincipalID = OLD.PrincipalID'
|
||||||
];
|
];
|
||||||
|
@ -25,10 +26,13 @@ class MigrationManager
|
||||||
'ALTER TABLE mcp_regions_info MODIFY COLUMN regionID CHAR(36), MODIFY COLUMN ProcMem INT(11) UNSIGNED NOT NULL, MODIFY COLUMN Prims INT(11) UNSIGNED NOT NULL, MODIFY COLUMN SimFPS FLOAT NOT NULL, MODIFY COLUMN PhyFPS FLOAT NOT NULL, MODIFY COLUMN OfflineTimer BIGINT UNSIGNED NOT NULL DEFAULT 0',
|
'ALTER TABLE mcp_regions_info MODIFY COLUMN regionID CHAR(36), MODIFY COLUMN ProcMem INT(11) UNSIGNED NOT NULL, MODIFY COLUMN Prims INT(11) UNSIGNED NOT NULL, MODIFY COLUMN SimFPS FLOAT NOT NULL, MODIFY COLUMN PhyFPS FLOAT NOT NULL, MODIFY COLUMN OfflineTimer BIGINT UNSIGNED NOT NULL DEFAULT 0',
|
||||||
'CREATE TRIGGER IF NOT EXISTS del_id_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_user_identities WHERE mcp_user_identities.PrincipalID = OLD.PrincipalID OR mcp_user_identities.IdentityID = OLD.PrincipalID',
|
'CREATE TRIGGER IF NOT EXISTS del_id_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_user_identities WHERE mcp_user_identities.PrincipalID = OLD.PrincipalID OR mcp_user_identities.IdentityID = OLD.PrincipalID',
|
||||||
'CREATE TRIGGER IF NOT EXISTS del_pwres_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_password_reset WHERE mcp_password_reset.PrincipalID = OLD.PrincipalID'
|
'CREATE TRIGGER IF NOT EXISTS del_pwres_trig AFTER DELETE ON UserAccounts FOR EACH ROW DELETE FROM mcp_password_reset WHERE mcp_password_reset.PrincipalID = OLD.PrincipalID'
|
||||||
|
],
|
||||||
|
2 => [
|
||||||
|
'CREATE TABLE IF NOT EXISTS `mcp_cron_runs` (`Name` VARCHAR(50) NOT NULL, `LastRun` INT(11) UNSIGNED NOT NULL, PRIMARY KEY(`Name`)) ENGINE InnoDB'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
private const MIGRATE_VERSION_CURRENT = 2;
|
private const MIGRATE_VERSION_CURRENT = 3;
|
||||||
|
|
||||||
private int $migrateVersion;
|
private int $migrateVersion;
|
||||||
private string $migrateVersionFile;
|
private string $migrateVersionFile;
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Mcp\Api;
|
||||||
|
|
||||||
|
use Mcp\RequestHandler;
|
||||||
|
|
||||||
|
class CronStarter extends RequestHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
private const CRONJOBS_INTERNAL = ['SessionCleanup'];
|
||||||
|
|
||||||
|
public function get(): void
|
||||||
|
{
|
||||||
|
if ($this->app->config('cron-restriction') == 'key' && !(isset($_GET['key']) && hash_equals($this->app->config('cron-key'), $_GET['key']))) {
|
||||||
|
http_response_code(403);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cronJobs = array_merge($this->app->config('cronjobs'), $this::CRONJOBS_INTERNAL);
|
||||||
|
|
||||||
|
$cronStatement = $this->app->db()->prepare('SELECT Name,LastRun FROM mcp_cron_runs');
|
||||||
|
$cronStatement->execute();
|
||||||
|
|
||||||
|
$jobRuns = array();
|
||||||
|
while ($row = $cronStatement->fetch()) {
|
||||||
|
$jobRuns[$row['Name']] = $row['LastRun'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$cronUpdateStatement = $this->app->db()->prepare('REPLACE INTO mcp_cron_runs(Name,LastRun) VALUES (?,?)');
|
||||||
|
foreach ($cronJobs as $jobName) {
|
||||||
|
$jobClass = "Mcp\\Cron\\".$jobName;
|
||||||
|
if (in_array($jobName, $cronJobs)) {
|
||||||
|
$job = (new $jobClass($this->app));
|
||||||
|
$now = time();
|
||||||
|
$nextRun = $job->getNextRun(isset($jobRuns[$jobName]) ? $jobRuns[$jobName] : $now - 60);
|
||||||
|
if ($now >= $nextRun && $job->run()) {
|
||||||
|
error_log($now.' <= '.$nextRun);
|
||||||
|
$cronUpdateStatement->execute([$jobName, time()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Mcp\Cron;
|
||||||
|
|
||||||
|
use DateInterval;
|
||||||
|
use DateTime;
|
||||||
|
use Mcp\Mcp;
|
||||||
|
|
||||||
|
abstract class CronJob {
|
||||||
|
|
||||||
|
protected Mcp $app;
|
||||||
|
private Frequency $freq;
|
||||||
|
|
||||||
|
public function __construct(Mcp $app, Frequency $freq)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
$this->freq = $freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNextRun(int $lastRun)
|
||||||
|
{
|
||||||
|
$prevDate = getdate($lastRun);
|
||||||
|
$res = new DateTime('@'.$lastRun);
|
||||||
|
switch($this->freq) {
|
||||||
|
case Frequency::EACH_MINUTE:
|
||||||
|
$res->add(DateInterval::createFromDateString('1 minute'));
|
||||||
|
break;
|
||||||
|
case Frequency::HOURLY:
|
||||||
|
$res->add(DateInterval::createFromDateString('1 hour'));
|
||||||
|
break;
|
||||||
|
case Frequency::DAILY:
|
||||||
|
$res->add(DateInterval::createFromDateString('1 day'));
|
||||||
|
break;
|
||||||
|
case Frequency::WEEKLY:
|
||||||
|
$res->add(DateInterval::createFromDateString('1 week'));
|
||||||
|
break;
|
||||||
|
case Frequency::MONTHLY:
|
||||||
|
$res->setDate($prevDate['year'] + ($prevDate['mon'] == 12 ? 1 : 0), $prevDate['mon'] == 12 ? 1 : $prevDate['mon'] + 1, 1);
|
||||||
|
break;
|
||||||
|
case Frequency::YEARLY:
|
||||||
|
$res->setDate($prevDate['year'] + 1, 1, 1);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function run(): bool;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Mcp\Cron;
|
||||||
|
|
||||||
|
enum Frequency
|
||||||
|
{
|
||||||
|
case YEARLY;
|
||||||
|
case MONTHLY;
|
||||||
|
case WEEKLY;
|
||||||
|
case DAILY;
|
||||||
|
case HOURLY;
|
||||||
|
case EACH_MINUTE;
|
||||||
|
}
|
24
cron.php
24
cron.php
|
@ -1,24 +0,0 @@
|
||||||
<?php
|
|
||||||
$RUNTIME = array();
|
|
||||||
$RUNTIME['BASEDIR'] = __DIR__;
|
|
||||||
set_include_path('.:'.$RUNTIME['BASEDIR']);
|
|
||||||
include_once "config.php";
|
|
||||||
|
|
||||||
if(!isset($RUNTIME['CRON_RESTRICTION'])) {
|
|
||||||
http_response_code(500);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($RUNTIME['CRON_RESTRICTION'] != 'none' && (!isset($RUNTIME['CRON_KEY']) || !isset($REQUEST['key']) || $_REQUEST['key'] !== $RUNTIME['CRON_KEY'])) {
|
|
||||||
http_response_code(401);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($handle = opendir('./cron/')) {
|
|
||||||
while (false !== ($entry = readdir($handle))) {
|
|
||||||
if ($entry != "." && $entry != "..") {
|
|
||||||
include_once "./cron/".$entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir($handle);
|
|
||||||
}
|
|
Loading…
Reference in New Issue