689b9c8de2945e241230471bf1920f2a29aaa74b
4 * Class for managing forking command line scripts.
5 * Currently just does forking and process control, but it could easily be extended
6 * to provide IPC and job dispatch.
9 var $children = array();
10 var $termReceived = false;
12 public function __construct() {
13 if ( php_sapi_name() != 'cli' ) {
14 throw new MWException( "MultiProcess cannot be used from the web." );
18 protected function prepareEnvironment() {
19 global $wgCaches, $wgMemc;
20 // Don't share DB or memcached connections
21 wfGetLBFactory()->destroyInstance();
27 * Fork a number of worker processes.
29 * This should only be called from the command line. It should be called
30 * as early as possible during execution. It will return 'child' in the
31 * child processes and 'parent' in the parent process. The parent process
32 * should then call monitor().
34 * This function requires the posix and pcntl extensions.
36 public function forkWorkers( $numProcs ) {
37 global $wgMemc, $wgCaches, $wgMainCacheType;
39 $this->prepareEnvironment();
41 // Create the child processes
42 for ( $i = 0; $i < $numProcs; $i++
) {
45 if ( $pid === -1 ||
$pid === false ) {
46 echo "Error creating child processes\n";
52 $this->children
= null;
55 // This is the parent process
56 $this->children
[$pid] = true;
64 * The parent process main loop
66 public function runParent() {
68 pcntl_signal( SIGTERM
, array( $this, 'handleTermSignal' ), false );
72 $deadPid = pcntl_wait( $status );
75 unset( $this->children
[$deadPid] );
78 // Run signal handlers
79 if ( function_exists( 'pcntl_signal_dispatch' ) ) {
80 pcntl_signal_dispatch();
82 declare (ticks
=1) { $status = $status; }
84 // Respond to TERM signal
85 if ( $this->termReceived
) {
86 foreach ( $this->children
as $childPid => $unused ) {
87 posix_kill( $childPid, SIGTERM
);
89 $this->termReceived
= false;
91 } while ( count( $this->children
) );
92 pcntl_signal( SIGTERM
, SIG_DFL
);
95 protected function initChild() {
96 global $wgMemc, $wgMainCacheType;
97 $wgMemc = wfGetCache( $wgMainCacheType );
100 protected function handleTermSignal( $signal ) {
101 $this->termReceived
= true;