diff --git a/src/Command/DaemonCommand.php b/src/Command/DaemonCommand.php index ce65911..60c3bf1 100644 --- a/src/Command/DaemonCommand.php +++ b/src/Command/DaemonCommand.php @@ -46,6 +46,12 @@ class DaemonCommand extends Command while(1) { if($endofscript !== false && time() > $endofscript) break; + + $maxwait = time() + 10; + $nextrun = $jobRepo->getTimeOfNextRun(); + $sleepuntil = min($maxwait, $nextrun); + if($sleepuntil > time()) time_sleep_until($sleepuntil); + $jobsToRun = $jobRepo->getJobsDue(); if(!empty($jobsToRun)) { foreach($jobsToRun as $job) { @@ -76,7 +82,6 @@ class DaemonCommand extends Command } } - sleep(1); } $output->writeln('Ended after ' . $timelimit . ' seconds'); pcntl_wait($status); diff --git a/src/Repository/Job.php b/src/Repository/Job.php index 4af3917..7afe927 100644 --- a/src/Repository/Job.php +++ b/src/Repository/Job.php @@ -77,6 +77,52 @@ class Job extends Repository return $jobs; } + public function getTimeOfNextRun() + { + $jobsSql = "SELECT nextrun + FROM job + WHERE running = 0 and nextrun != :time + ORDER BY nextrun + LIMIT 1"; + $jobsStmt = $this->dbcon->prepare($jobsSql); + $jobsRslt = $jobsStmt->executeQuery([':time' => time()]); + $nextjob = $jobsRslt->fetchAssociative(); + + + $jobsSql = "SELECT nextrun + FROM job + WHERE running = 2 + ORDER BY nextrun + LIMIT 1"; + $jobsStmt = $this->dbcon->prepare($jobsSql); + $jobsRslt = $jobsStmt->executeQuery(); + $manualjob = $jobsRslt->fetchAssociative(); + + if($nextjob == false && $manualjob == false) { + return PHP_INT_MAX; + } + + if($manualjob != false) { + return 100; + } + + + $jobsSql = "SELECT running + FROM job + WHERE running > 2 + ORDER BY nextrun DESC + LIMIT 1"; + $jobsStmt = $this->dbcon->prepare($jobsSql); + $jobsRslt = $jobsStmt->executeQuery(); + $running = $jobsRslt->fetchAssociative(); + + if($running == false) { + return (int)$nextjob['nextrun']; + } + + return $nextjob < $running ? (int)$running ['running']: (int)$nextjob['nextrun']; + } + public function setJobRunning(int $job, bool $status): void { $jobsSql = "UPDATE job SET running = :status WHERE id = :id AND running IN (0,1,2)";