Login   Register  
PHP Classes
elePHPant
Icontem

File: action_dispatcher.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Luca Mariano  >  Thread  >  action_dispatcher.php  >  Download  
File: action_dispatcher.php
Role: Example script
Content type: text/plain
Description: shows a multiprocess application scheme where all processes run a sleep() cycle, and a centralized dispatcher pass them the work.
Class: Thread
A class to implement multi-threaded applications
Author: By
Last change:
Date: 2003-12-09 02:13
Size: 6,149 bytes
 

Contents

Class file image Download
<?php
/**
 * PHP_Fork class usage examples
 * ==================================================================================
 * NOTE: In real world you surely want to keep each class into
 * a separate file, then include() it into your application.
 * For this examples is more useful to keep all_code_into_one_file,
 * so that each example shows a unique feature of the PHP_Fork framework.
 * ==================================================================================
 * action_dispatcher.php
 *
 * This example shows a multi-process application model built using PHP_Fork.
 * Execute-threads makes the work, but they don't use the infinite cycle run();
 * work are passed from the parent (console) to pseudo-thread using a remote
 * method call (PHP_FORK_VOID_METHOD), simulating the behaviour of a centralized
 * calls dispatcher.
 *
 *
 * ATTENTION: this feature of PHP_Fork is highly experimental;
 * all things are OK until we run such an example, that does nothing and simply
 * sleep() all time waiting for a call. Some experiement with real applications
 * seems to show that firing the child process with a signal (that is part of the
 * workaround...) causes the process to stop execution, and then to repeat ALL the
 * run() method after signal caught... This is not an acceptable behaviour and
 * should be tested better.
 *
 * ==================================================================================
 *
 * Copyright (c) 2003-2002 by Luca Mariano (luca.mariano@email.it)
 * http://www.lucamariano.it
 *
 * This program is free software. You can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 */
// Import of base class
require_once ("../Fork.php");
// Import of PEAR Mail class
require_once ("Mail.php");
// number of executeThreads we want
define ("NUM_THREAD"10);
// SMTP host to use for mailing
define ("SMTP_TEST_HOST""smtp.consulenti.csi.it");
// The example will send a lot of mails to this address, so keep sure it's one of yours...
define ("MAIL_RECIPIENT""luca.mariano@consulenti.csi.it");
// this is needed as PHP 4.3 in order to use pcntl_signal()
declare (ticks 1);

/**
 *
 * executeThread class inherit from PHP_Fork and must redefine the run() method
 * all the code contained into the run() method will be executed only by the child
 * process; all other methods that you define will be accessible both to the parent
 * and to the child (and will be executed into the relative process)
 */
class executeThread extends PHP_Fork {
    function 
executeThread($name)
    {
        
$this->PHP_Fork($name);
    }

    function 
run()
    {
        
// this thread sits sleeping until the dispatcher pass some work to it...
        
while (true) {
            
sleep(60);
        }
    }

    function 
sendMail($msgObj)
    {
        if (
$this->_isChild) {
            
$msgObj = &$msgObj[0];
            
// to have a feedback of pseudo-thread cuncurrency level
            
$msgObj['subject'] .= " posted at " getmicrotime() . " from " $this->getName();

            
srand((double)microtime() * 1000000);

            
$params["host"] = "smtp.consulenti.csi.it";

            
$mail = &Mail::factory ("smtp"$params);

            
$headers['From'] = $msgObj['from'];
            
$headers['To'] = $msgObj['to'];
            
$headers['Subject'] = $msgObj['subject'] . "(" rand(0100000) . ")" ;

            
$mail->send($msgObj['to'], $headers$msgObj['body'] . "\n" rand(0100000));
        }
        
/**
         * Never change this line, it requires no adjustments...
         */
        
else return $this->register_callback_func(func_get_args(), __FUNCTION__);
    }
}

/**
 * Functions used by the console
 */
function _getInputCLI()
{
    
$opt _read();
    
$opt strtoupper (trim($opt));
    return 
$opt;
}

function 
_read()
{
    
$fp fopen("php://stdin""r");
    
$input fgets($fp255);
    
fclose($fp);

    return 
$input;
}

function 
getmicrotime()
{
    list(
$usec$sec) = explode(" "microtime());
    return ((float)
$usec + (float)$sec);
}
/**
 * Main program. Bring up n instances of the executeThread class that
 * runs concurrently. It's a multi-thread app with a few lines of code!!!
 */
for ($i 0;$i NUM_THREAD;$i++) {
    
$executeThread[$i] = &new executeThread ("executeThread-" $i);
    
$executeThread[$i]->start();
    echo 
"Started " $executeThread[$i]->getName() . " with PID " $executeThread[$i]->getPid() . "...\n";
}

print 
"This is the main process.\nPress [X] to terminate, [S] tells executeThreads to send " NUM_THREAD " mail msgs\n";

/**
 * Console simple listener
 */
while (true) {
    echo 
">";

    
$opt _getInputCLI();
    echo 
"\n";
    switch (
$opt) {
        case 
"X":
            
// stops all threads
            
for ($i 0;$i NUM_THREAD;$i++) {
                
$executeThread[$i]->stop();
                echo 
"Stopped " $executeThread[$i]->getName() . "\n";
            }
            exit;
            break;

        case 
"S":

            
// compose the mail; here data are fixed, in a real application
            // data are read from a DB table (or a socket, a named pipe, etc)
            
$msgObj = array();
            
$msgObj['to'] = MAIL_RECIPIENT;
            
$msgObj['from'] = "foo@foo.it";
            
$msgObj['subject'] = "PHP_Fork test ";
            
$msgObj['body'] = "Main program created this message at " getmicrotime();

            echo 
"Sending mail to " NUM_THREAD " addresses...\n";
            
$time_start getmicrotime();

            
// tells all running processes to send the same mail
            // in real word we should test if the the process is busy;
            // if not, we'll pass to it a $msgObj to process, then we'll remove
            // the $msgObj from message queue.
            
for ($i 0;$i NUM_THREAD;$i++) {
                
$executeThread[$i]->sendMail($msgObj);
            }
            
$time_end getmicrotime();
            
$time $time_end $time_start;
            echo 
"Done! Elapsed " $time ", avg " . (($time NUM_THREAD) * 1000) . " msecs/msg \n";
            break;
    }
}

?>