Last active
October 3, 2015 18:28
-
-
Save Fizzadar/2504433 to your computer and use it in GitHub Desktop.
PHP Daemon Class
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
<?php | |
/* | |
file: app/lib/daemon.php | |
desc: daemon class | |
*/ | |
class mod_daemon { | |
private $jobs = array(); | |
private $threads = array(); | |
private $dbfunc; | |
private $threadfunc; | |
private $maxthreads; | |
private $threadtime; | |
private $dbupdate; | |
private $lock; | |
private $stopthreads; | |
//construct | |
public function __construct( $dbfunc, $threadfunc, $maxthreads = 10, $threadtime = 60, $dbupdate = 300, $lock = '', $stopthreads = 0 ) { | |
//basic data | |
$this->dbfunc = $dbfunc; | |
$this->threadfunc = $threadfunc; | |
$this->maxthreads = $maxthreads; | |
$this->threadtime = $threadtime; | |
$this->dbupdate = $dbupdate; | |
//lock file | |
if( empty( $lock ) ) | |
$this->lock = 'tmp/' . $threadfunc . '.lock'; | |
else | |
$this->lock = 'tmp/' . $lock . '.lock'; | |
//max threads before stopping daemon | |
$this->stopthreads = $stopthreads; | |
} | |
//run daemon | |
public function start() { | |
global $argv; | |
$arg = count( $argv ) - 1; | |
//check for lock file | |
if( file_exists( $this->lock ) and filemtime( $this->lock ) > time() - 60 and ( !isset( $argv[$arg] ) or $argv[$arg] != 'force' ) ): | |
echo $this->threadfunc . ' lock file in place, daemon exiting' . PHP_EOL; | |
return; | |
elseif( file_exists( $this->lock ) and isset( $argv[$arg] ) and $argv[$arg] == 'force' ): | |
posix_kill( file_get_contents( $this->lock ), SIGKILL ); | |
unlink( $this->lock ); | |
echo 'dead previous daemon killed ' . PHP_EOL; | |
endif; | |
//create lock file | |
file_put_contents( $this->lock, posix_getpid() ); | |
echo 'lock file created' . PHP_EOL; | |
//threads array & counter | |
$threadcount = 0; | |
//db update time | |
$dbtime = $this->dbupdate; | |
//loop time | |
while( true and ( $this->stopthreads == 0 or $threadcount < $this->stopthreads ) ): | |
//get new jobs (if current queue less than maxthreads, and threads less than max, and db time) | |
if( count( $this->jobs ) < $this->maxthreads and count( $this->threads ) < $this->maxthreads and $dbtime >= $this->dbupdate ): | |
//get jobs | |
$j = call_user_func( $this->dbfunc ); | |
echo 'daemon has ' . count( $j ) . ' jobs' . PHP_EOL; | |
foreach( $j as $job ): | |
$this->jobs[] = $job; | |
endforeach; | |
//reset db timer | |
$dbtime = 0; | |
elseif( count( $this->jobs ) <= 0 and count( $this->threads ) <= 0 ): | |
echo 'waiting for dbtimer... ' . ( $this->dbupdate - $dbtime ) . PHP_EOL; | |
endif; | |
//add threads until max reached | |
while( count( $this->threads ) < $this->maxthreads and count( $this->jobs ) > 0 ): | |
//get our job | |
reset( $this->jobs ); | |
$key = key( $this->jobs ); | |
//create thread | |
$this->threads[$threadcount] = array( | |
'thread' => new Thread( $this->threadfunc ), | |
'time' => 0, | |
'job' => $key | |
); | |
//start thread | |
$this->threads[$threadcount]['thread']->start( $this->jobs[$key] ); | |
echo 'new thread spawned: #' . $threadcount . PHP_EOL; | |
$threadcount++; | |
//remove from job queue | |
unset( $this->jobs[$key] ); | |
endwhile; | |
//check for threads | |
$this->checkThreads(); | |
//end, sleep, update timers | |
sleep( 1 ); | |
$dbtime++; | |
//touch our lock file | |
touch( $this->lock ); | |
endwhile; | |
//we're here? stopthreads must be set | |
while( count( $this->threads ) > 0 ): | |
//check for threads | |
$this->checkThreads(); | |
sleep( 1 ); | |
endwhile; | |
//and we're done, remove the lock file | |
unlink( $this->lock ); | |
echo 'daemon run over: ' . $this->lock . ' freed' . PHP_EOL; | |
exit( 0 ); | |
} | |
//check threads | |
public function checkThreads() { | |
//loop all current threads, check if dead | |
foreach( $this->threads as $key => $thread ): | |
//update thread timer | |
$this->threads[$key]['time']++; | |
//thread dead? | |
if( !$thread['thread']->isAlive() ): | |
unset( $this->threads[$key] ); | |
echo 'thread stopped: #' . $key . PHP_EOL; | |
endif; | |
//thread over times timer? | |
if( $thread['time'] > $this->threadtime ): | |
$thread['thread']->stop(); | |
unset( $this->threads[$key] ); | |
echo 'thread force-stopped: #' . $key . PHP_EOL; | |
endif; | |
endforeach; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment