]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - maintenance/gearman/gearman.inc
MediaWiki 1.15.0
[autoinstalls/mediawiki.git] / maintenance / gearman / gearman.inc
1 <?php
2
3 require( 'Net/Gearman/Client.php' );
4 require( 'Net/Gearman/Worker.php' );
5
6 class MWGearmanJob extends Net_Gearman_Job_Common {
7         function switchWiki( $wiki, $params ) {
8                 echo "Switching to $wiki\n";
9
10                 # Pretend that we have completed it right now, because the new process won't do it
11                 $this->complete( array( 'result' => true ) );
12                 socket_close( $this->conn );
13
14                 # Close some more sockets
15                 wfGetLBFactory()->shutdown();
16                 global $wgMemc;
17                 $wgMemc->disconnect_all();
18
19                 # Find PHP
20                 $php = readlink( '/proc/' . posix_getpid() . '/exe' );
21                 
22                 # Run the worker script
23                 $args = array( $_SERVER['PHP_SELF'], 
24                         '--wiki', $wiki,
25                         '--fake-job', serialize( $params ) );
26                 $args = array_merge( $args, $GLOBALS['args'] );
27                 pcntl_exec( $php, $args, $_ENV );
28                 echo "Error running exec\n";
29         }
30
31         function run( $params ) {
32                 if ( wfWikiID() !== $params['wiki'] ) {
33                         $this->switchWiki( $params['wiki'], $params );
34                 }
35                 return self::runNoSwitch( $params );
36         }
37
38         static function runNoSwitch( $params ) {
39                 echo implode( ' ', $params ) . "\n";
40                 $title = Title::newFromText( $params['title'] );
41                 $mwJob = Job::factory( $params['command'], $title, $params['params'] );
42                 return $mwJob->run();
43         }
44 }
45
46 class NonScaryGearmanWorker extends Net_Gearman_Worker {
47         
48         /**
49          * Copied from Net_Gearman_Worker but with the scary "run any PHP file in 
50          * the filesystem" feature removed.
51          */
52         protected function doWork($socket) {
53                 Net_Gearman_Connection::send($socket, 'grab_job');
54
55                 $resp = array('function' => 'noop');
56                 while (count($resp) && $resp['function'] == 'noop') {
57                         $resp = Net_Gearman_Connection::blockingRead($socket);
58                 } 
59
60                 if (in_array($resp['function'], array('noop', 'no_job'))) {
61                         return false;
62                 }
63
64                 if ($resp['function'] != 'job_assign') {
65                         throw new Net_Gearman_Exception('Holy Cow! What are you doing?!');
66                 }
67
68                 $name   = $resp['data']['func'];
69                 $handle = $resp['data']['handle'];
70                 $arg    = array();
71
72                 if (isset($resp['data']['arg']) && 
73                         Net_Gearman_Connection::stringLength($resp['data']['arg'])) {
74                                 $arg = json_decode($resp['data']['arg'], true);
75                         }
76
77                 ### START MW DIFFERENT BIT
78                 if ( $name != 'mw_job' ) {
79                         throw new Net_Gearman_Job_Exception('Invalid function');
80                 }
81                 $job = new MWGearmanJob($socket, $handle);
82                 ### END MW DIFFERENT BIT
83
84                 try {
85                         $this->start($handle, $name, $arg);
86                         $res = $job->run($arg); 
87                         if (!is_array($res)) {
88                                 $res = array('result' => $res);
89                         }
90
91                         $job->complete($res);
92                         $this->complete($handle, $name, $res);
93                 } catch (Net_Gearman_Job_Exception $e) {
94                         $job->fail(); 
95                         $this->fail($handle, $name, $e); 
96                 }
97
98                 // Force the job's destructor to run
99                 $job = null;
100
101                 return true;
102         }
103 }
104