Last active
November 27, 2021 11:23
-
-
Save lcherone/28b92af0f06c1224b30fe734a0d51877 to your computer and use it in GitHub Desktop.
CRON PHP Daemon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php | |
<?php | |
/** | |
* Need to test code works on ©Win"virus"dow$ | |
* | |
* Aim: | |
* To run code within a cron task at a settable frequency above 1 per minute, | |
* but not overrun the minute or run again if already running, tasks should | |
* also complete at their own pace within the minute. | |
* | |
* Solution: | |
* | |
* Controlling state: | |
* Define the state by setting a variable as false, look for a pid file, | |
* if the pid file is found but the variable is not running, assume the script | |
* died prematurely, attempt to kill the process, write new pid to file. | |
* | |
* Code iteration frequency: | |
* Using a while loop watch the time() + 60 !> time() this makes it much | |
* simpler to define our sleep time and turns time back into a frequency rather | |
* then a calculation. | |
* | |
* Setup cron to run every minute (brakes if task breaks): | |
* * * * * * /usr/bin/php /home/lozza/cron.php | |
* Setup cron to run at start but continue to run (restarts if task breaks - watchdog): | |
* @reboot while sleep 1; do cd /home/lozza && /usr/bin/php cron.php ; done | |
*/ | |
class pid | |
{ | |
protected $pidfile; | |
public $running = false; | |
public function __construct($directory = '') | |
{ | |
$this->pidfile = (!empty($directory) ? $directory.'/' : null) . basename($_SERVER['PHP_SELF']) . '.pid'; | |
if (is_writable($this->pidfile) || is_writable($directory)) { | |
if (file_exists($this->pidfile)) { | |
$pid = (int) trim(file_get_contents($this->pidfile)); | |
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | |
$wmi = new COM("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2"); | |
$procs = $wmi->ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId='".$pid."'"); | |
foreach ($procs as $proc) { | |
$proc->Terminate(); | |
$this->running = true; | |
} | |
} else { | |
if (posix_kill($pid, 0)) { | |
$this->running = true; | |
} | |
} | |
} | |
} else { | |
die("Cannot write to pid file '{$this->pidfile}'. Program execution halted.\n"); | |
} | |
if (!$this->running) { | |
file_put_contents($this->pidfile, getmypid()); | |
} | |
} | |
public function __destruct() | |
{ | |
if (!$this->running && file_exists($this->pidfile) && is_writeable($this->pidfile)) { | |
unlink($this->pidfile); | |
} | |
} | |
} | |
$pid = new pid(dirname(__FILE__)); | |
if ($pid->running) { | |
exit; | |
} else { | |
$stopTime = microtime(true) + 60; | |
$i = 1; | |
while (microtime(true) < $stopTime) { | |
// time iteration as not to be running when next cron runs ... | |
$loopStart = microtime(true); | |
### do your code | |
//echo $i.PHP_EOL; | |
$i++; | |
// stop if next task will overrun minute | |
if ((microtime(true)+(microtime(true) - $loopStart)) > $stopTime) { | |
break; | |
} | |
// Run 943995 times within the minute = usleep(1000) = slow but dont 100% CPU | |
usleep(1000); | |
// without! | |
// Run 19037412 times within the minute, but 100% CPU | |
//usleep(0); | |
} | |
echo 'Run '.$i.' times within the minute'.PHP_EOL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment