From 9cc49f27e6fd713bc41831f19decd1460c244544 Mon Sep 17 00:00:00 2001 From: Mike Macgirvin Date: Tue, 6 Jul 2010 23:08:38 -0700 Subject: [PATCH] minor stuff, getting ready for notify --- include/notifier.php | 242 +++++++++++++++++++++++++++++++++++++++++++ mod/item.php | 6 ++ view/atomic.tpl | 22 ++++ wip/procs | 9 ++ 4 files changed, 279 insertions(+) create mode 100644 include/notifier.php create mode 100644 view/atomic.tpl create mode 100644 wip/procs diff --git a/include/notifier.php b/include/notifier.php new file mode 100644 index 000000000..0beb72cd0 --- /dev/null +++ b/include/notifier.php @@ -0,0 +1,242 @@ + + + +If you want to execute some code after your php page has been returned to the user. Try something like this - + + + +while(count($this->currentJobs) >= $this->maxProcesses){ + echo "Maximum children allowed, waiting...\n"; + sleep(1); +} +duerra at yahoo dot com +02-Jul-2010 02:06 +Using pcntl_fork() can be a little tricky in some situations. For fast jobs, a child can finish processing before the parent process has executed some code related to the launching of the process. The parent can receive a signal before it's ready to handle the child process' status. To handle this scenario, I add an id to a "queue" of processes in the signal handler that need to be cleaned up if the parent process is not yet ready to handle them. + +I am including a stripped down version of a job daemon that should get a person on the right track. + +parentPID = getmypid(); + pcntl_signal(SIGCHLD, array($this, "childSignalHandler")); + } + + /** + * Run the Daemon + */ + public function run(){ + echo "Running \n"; + for($i=0; $i<10000; $i++){ + $jobID = rand(0,10000000000000); + $launched = $this->launchJob($jobID); + } + + //Wait for child processes to finish before exiting here + while(count($this->currentJobs)){ + echo "Waiting for current jobs to finish... \n"; + sleep(1); + } + } + + /** + * Launch a job from the job queue + */ + protected function launchJob($jobID){ + $pid = pcntl_fork(); + if($pid == -1){ + //Problem launching the job + error_log('Could not launch new job, exiting'); + return false; + } + else if ($pid){ + // Parent process + // Sometimes you can receive a signal to the childSignalHandler function before this code executes if + // the child script executes quickly enough! + // + $this->currentJobs[$pid] = $jobID; + + // In the event that a signal for this pid was caught before we get here, it will be in our signalQueue array + // So let's go ahead and process it now as if we'd just received the signal + if(isset($this->signalQueue[$pid])){ + echo "found $pid in the signal queue, processing it now \n"; + $this->childSignalHandler(SIGCHLD, $pid, $this->signalQueue[$pid]); + unset($this->signalQueue[$pid]); + } + } + else{ + //Forked child, do your deeds.... + $exitStatus = 0; //Error code if you need to or whatever + echo "Doing something fun in pid ".getmypid()."\n"; + exit($exitStatus); + } + return true; + } + + public function childSignalHandler($signo, $pid=null, $status=null){ + + //If no pid is provided, that means we're getting the signal from the system. Let's figure out + //which child process ended + if(!$pid){ + $pid = pcntl_waitpid(-1, $status, WNOHANG); + } + + //Make sure we get all of the exited children + while($pid > 0){ + if($pid && isset($this->currentJobs[$pid])){ + $exitCode = pcntl_wexitstatus($status); + if($exitCode != 0){ + echo "$pid exited with status ".$exitCode."\n"; + } + unset($this->currentJobs[$pid]); + } + else if($pid){ + //Oh no, our job has finished before this parent process could even note that it had been launched! + //Let's make note of it and handle it when the parent process is ready for it + echo "..... Adding $pid to the signal queue ..... \n"; + $this->signalQueue[$pid] = $status; + } + $pid = pcntl_waitpid(-1, $status, WNOHANG); + } + return true; + } +} + + + +*/ + + + +function notifier(&$a,$item_id,$parent_id) { + + $pid = pcntl_fork(); + + if ($pid == (-1)) { + notice("Failed to launch background notifier." . EOL ); + return; + } + + if ($pid > 0) { + // parent process - regenerate our connections in case the kid kills them + + @include(".htconfig.php"); + $db = new dba($db_host, $db_user, $db_pass, $db_data, $install); + unset($db_host, $db_user, $db_pass, $db_data); + session_write_close(); + session_start(); + + // go back and finish the page + return; + } + else { + // We are the child + + // fetch item + + // if not parent, fetch it + + // atomify + + // expand list of recipients + + // grab the contact records + + // foreach recipient + + // if no dfrn-id continue + + // fetch_url dfrn-notify + + // decrypt challenge + + // post result + + // continue + + killme(); + } +} diff --git a/mod/item.php b/mod/item.php index f667d4fc4..1c1fd5029 100644 --- a/mod/item.php +++ b/mod/item.php @@ -57,6 +57,12 @@ function item_post(&$a) { intval($parent), intval($post_id)); } + + require('notifier.php'); + + + notifier(&$a,$post_id,$parent); + } goaway($a->get_baseurl() . "/profile/$profile_uid"); diff --git a/view/atomic.tpl b/view/atomic.tpl new file mode 100644 index 000000000..133933303 --- /dev/null +++ b/view/atomic.tpl @@ -0,0 +1,22 @@ + + $feed_id + $feed_title + $feed_updated + + + $name + + + + + + + $item_id + $title + + $updated + $summary + + + \ No newline at end of file diff --git a/wip/procs b/wip/procs new file mode 100644 index 000000000..369c68529 --- /dev/null +++ b/wip/procs @@ -0,0 +1,9 @@ +You could use proc_open for this: + +proc_close(proc_open ("./script.php &", array(), $foo)); + +The empty array for the output specs prevents opening any pipes to the new +process, so proc_open doesn't wait for the execution of script.php to +finish - the last parameter is just there because it has to be. +proc_close() closes the process immediately, so your PHP script doesn't +stop. \ No newline at end of file