public function execute() { global $wgTitle; if ( $this->hasOption( 'procs' ) ) { $procs = intval( $this->getOption( 'procs' ) ); if ( $procs < 1 || $procs > 1000 ) { $this->error( "Invalid argument to --procs", true ); } $fc = new ForkController( $procs ); if ( $fc->start() != 'child' ) { exit( 0 ); } } $maxJobs = $this->getOption( 'maxjobs', false ); $maxTime = $this->getOption( 'maxtime', false ); $startTime = time(); $type = $this->getOption( 'type', false ); $wgTitle = Title::newFromText( 'RunJobs.php' ); $dbw = wfGetDB( DB_MASTER ); $n = 0; $conds = ''; if ( $type !== false ) { $conds = "job_cmd = " . $dbw->addQuotes( $type ); } while ( $dbw->selectField( 'job', 'job_id', $conds, 'runJobs.php' ) ) { $offset = 0; for ( ; ; ) { $job = !$type ? Job::pop( $offset ) : Job::pop_type( $type ); if ( !$job ) { break; } wfWaitForSlaves( 5 ); $t = microtime( true ); $offset = $job->id; $status = $job->run(); $t = microtime( true ) - $t; $timeMs = intval( $t * 1000 ); if ( !$status ) { $this->runJobsLog( $job->toString() . " t=$timeMs error={$job->error}" ); } else { $this->runJobsLog( $job->toString() . " t=$timeMs good" ); } if ( $maxJobs && ++$n > $maxJobs ) { break 2; } if ( $maxTime && time() - $startTime > $maxTime ) { break 2; } } } }
public function execute() { global $wgTitle; if ($this->hasOption('procs')) { $procs = intval($this->getOption('procs')); if ($procs < 1 || $procs > 1000) { $this->error("Invalid argument to --procs", true); } $fc = new ForkController($procs); if ($fc->start() != 'child') { exit(0); } } $maxJobs = $this->getOption('maxjobs', false); $maxTime = $this->getOption('maxtime', false); $startTime = time(); $type = $this->getOption('type', false); $wgTitle = Title::newFromText('RunJobs.php'); $dbw = wfGetDB(DB_MASTER); $n = 0; $conds = ''; if ($type !== false) { $conds = "job_cmd = " . $dbw->addQuotes($type); } while ($dbw->selectField('job', 'job_id', $conds, 'runJobs.php')) { $offset = 0; for (;;) { $job = !$type ? Job::pop($offset) : Job::pop_type($type); if (!$job) { break; } //check for similar (but not IDENTICAL (different timestamp allowed) jobs and delete them. $dbw->delete('job', array('job_cmd' => $job->command, 'job_title' => $job->title->getDBkey()), __METHOD__); wfWaitForSlaves(); $t = microtime(true); $offset = $job->id; $status = $job->run(); $t = microtime(true) - $t; $timeMs = intval($t * 1000); if (!$status) { $this->runJobsLog($job->toString() . " t={$timeMs} error={$job->error}"); } else { $this->runJobsLog($job->toString() . " t={$timeMs} good"); } if ($maxJobs && ++$n > $maxJobs) { break 2; } if ($maxTime && time() - $startTime > $maxTime) { break 2; } } } }
/** * Main entry point, tak job from queue and run it * * @access public */ public function execute() { global $wgUser, $wgApiRunJobsPerRequest; ini_set("memory_limit", -1); ini_set("max_execution_time", 0); $result = array(); $done = 0; # # check if wiki is not readonly # if (!wfReadOnly()) { $params = $this->extractRequestParams(); if (!$wgUser->isAllowed("runjob")) { $this->dieUsageMsg(array("cantrunjobs")); } # # api param has precedence # if (isset($params["max"])) { $max = $params["max"]; if (is_numeric($max) && $max > 0 && $max <= 100) { $this->maxJobs = $max; } } elseif (!empty($wgApiRunJobsPerRequest) && is_numeric($wgApiRunJobsPerRequest) && $wgApiRunJobsPerRequest > 0 && $wgApiRunJobsPerRequest <= 100) { $this->maxJobs = $wgApiRunJobsPerRequest; } foreach (range(1, $this->maxJobs) as $counter) { if (isset($params["type"])) { $job = Job::pop_type($params["type"]); } else { // refreshlinks2 has precedence $job = Job::pop_type("refreshLinks2"); if (!$job) { // any job $job = Job::pop(); } } if ($job) { $status = $job->run(); $result["job"][] = array("id" => $job->id, "type" => $job->command, "status" => $job->toString(), "error" => $job->error); $done++; } else { // there's no job in queue, finish loop, release request break; } } } $result["left"] = $this->checkQueue($done); $this->getResult()->addValue(null, $this->getModuleName(), $result); $result = array(); }
<?php $optionsWithArgs = array('maxjobs'); $wgUseNormalUser = true; require_once 'commandLine.inc'; require_once "{$IP}/includes/JobQueue.php"; require_once "{$IP}/includes/FakeTitle.php"; if (isset($options['maxjobs'])) { $maxJobs = $options['maxjobs']; } else { $maxJobs = 10000; } // Trigger errors on inappropriate use of $wgTitle $wgTitle = new FakeTitle(); $dbw =& wfGetDB(DB_MASTER); $n = 0; while ($dbw->selectField('job', 'count(*)', '', 'runJobs.php')) { while (false != ($job = Job::pop())) { wfWaitForSlaves(5); print $job->id . " " . $job->toString() . "\n"; if (!$job->run()) { print "Error: {$job->error}\n"; } if ($maxJobs && ++$n > $maxJobs) { break 2; } } }
/** * Do a job from the job queue */ function doJobs() { global $wgJobRunRate; if ($wgJobRunRate <= 0 || wfReadOnly()) { return; } if ($wgJobRunRate < 1) { $max = mt_getrandmax(); if (mt_rand(0, $max) > $max * $wgJobRunRate) { return; } $n = 1; } else { $n = intval($wgJobRunRate); } while ($n-- && false != ($job = Job::pop())) { $output = $job->toString() . "\n"; $t = -wfTime(); $success = $job->run(); $t += wfTime(); $t = round($t * 1000); if (!$success) { $output .= "Error: " . $job->getLastError() . ", Time: {$t} ms\n"; } else { $output .= "Success, Time: {$t} ms\n"; } wfDebugLog('jobqueue', $output); } }
for (;;) { // determine the most lagged slave // if $lag == -1, there's no slave. list($host, $lag) = LBFactory::singleton()->getMainLB()->getMaxLag(); if ($lag == -1) { // make sleeping time adaptive to database load. $runningThreads = smwfGetNumOfRunningThreads($dbw); $runningThreads = $runningThreads <= MAX_THREADS_CONSIDERED ? $runningThreads : MAX_THREADS_CONSIDERED; // wait depending on user-defined $rate and server load sleep(1 / $rate + $runningThreads); } else { // wait for most lagged slave to be *below* 1/$rate + 3 seconds lag time. wfWaitForSlaves(1 / $rate + 3); } // get next job $job = Job::pop(); // is there a break signal? $accept_sock = @socket_accept($socket); if ($accept_sock !== false) { socket_getpeername($accept_sock, $name); if ($name == '127.0.0.1') { // only stop, if request comes from localhost. // TODO: is this SAVE? spoofing? print "\n\nStopped."; socket_close($accept_sock); break; } } if ($job == false || $job == NULL) { continue; }
/** * Do a job from the job queue */ function doJobs() { global $wgJobLogFile, $wgJobRunRate; if ($wgJobRunRate <= 0) { return; } if ($wgJobRunRate < 1) { $max = mt_getrandmax(); if (mt_rand(0, $max) > $max * $wgJobRunRate) { return; } $n = 1; } else { $n = intval($wgJobRunRate); } require_once 'JobQueue.php'; while ($n-- && false != ($job = Job::pop())) { $output = $job->toString() . "\n"; if (!$job->run()) { $output .= "Error: " . $job->getLastError() . "\n"; } if ($wgJobLogFile) { error_log($output, 3, $wgJobLogFile); } } }
/** * Helper function to perform an async upload, execute the job and fetch * the status * * @return array The result of action=upload&statuskey=key */ private function doAsyncUpload($token, $ignoreWarnings = false, $leaveMessage = false) { $params = array('action' => 'upload', 'filename' => 'UploadFromUrlTest.png', 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', 'asyncdownload' => 1, 'token' => $token); if ($ignoreWarnings) { $params['ignorewarnings'] = 1; } if ($leaveMessage) { $params['leavemessage'] = 1; } $data = $this->doApiRequest($params); $this->assertEquals($data[0]['upload']['result'], 'Queued'); $this->assertTrue(isset($data[0]['upload']['statuskey'])); $statusKey = $data[0]['upload']['statuskey']; $job = Job::pop(); $this->assertEquals('UploadFromUrlJob', get_class($job)); $status = $job->run(); $this->assertTrue($status); $data = $this->doApiRequest(array('action' => 'upload', 'statuskey' => $statusKey, 'token' => $token)); return $data; }
function executeScript($type) { global $wgOut, $wgRequest, $wgUser; wfLoadExtensionMessages('Maintenance'); @set_time_limit(0); //if we can, disable the time limit $this->setHeaders(); $wgOut->addHTML($wgUser->getSkin()->makeKnownLinkObj($this->getTitle(), wfMsgHtml('maintenance-backlink')) . '<br />'); switch ($type) { case 'changePassword': $name = $wgRequest->getText('wpName'); $password = $wgRequest->getText('wpPassword'); $user = User::newFromName($name); if (!is_object($user) || !$user->getId()) { $wgOut->addWikiMsg('maintenance-invalidname'); return; } $dbw = wfGetDB(DB_MASTER); $user->setPassword($password); $user->saveSettings(); $wgOut->addWikiMsg('maintenance-success', $type); break; case 'createAndPromote': $name = $wgRequest->getText('wpName'); $password = $wgRequest->getText('wpPassword'); $bcrat = $wgRequest->getCheck('wpBcrat'); $user = User::newFromName($name); if (!is_object($user)) { $wgOut->addWikiMsg('maintenance-invalidname'); return; } elseif (0 != $user->idForName()) { $wgOut->addWikiMsg('maintenance-userexists'); return; } $user->addToDatabase(); $user->setPassword($password); $user->saveSettings(); $user->addGroup('sysop'); if ($bcrat) { $user->addGroup('bureaucrat'); } $ssu = new SiteStatsUpdate(0, 0, 0, 0, 1); $ssu->doUpdate(); $wgOut->addWikiMsg('maintenance-success', $type); break; case 'deleteBatch': $reason = $wgRequest->getText('wpReason', ''); $interval = 0; $pages = $wgRequest->getText('wpDelete'); $dbw = wfGetDB(DB_MASTER); $lines = explode("\n", $pages); foreach ($lines as &$line) { $line = trim($line); if ($line == '') { continue; } $page = Title::newFromText($line); if (is_null($page)) { $wgOut->addWikiMsg('maintenance-invalidtitle', $line); continue; } if (!$page->exists()) { $wgOut->addWikiMsg('maintenance-titlenoexist', $line); continue; } $return = '* ' . $page->getPrefixedText(); // Switch the user here from the current user to Delete page script $OldUser = $wgUser; $wgUser = User::newFromName('Delete page script'); // Begin transaction $dbw->begin(); if ($page->getNamespace() == NS_IMAGE) { $art = new ImagePage($page); $img = wfFindFile($art->mTitle); if (!$img || !$img->delete($reason)) { $return .= '... ' . wfMsg('maintenance-failed'); } } else { $art = new Article($page); } $success = $art->doDeleteArticle($reason); // Commit changes to the database $dbw->commit(); // ...and switch user back to the old user $wgUser = $OldUser; if ($success) { $return .= '... ' . wfMsg('maintenance-deleted'); } else { $return .= '... ' . wfMsg('maintenance-failed'); } $wgOut->addWikiText($return); waitForSlaves(5); } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'deleteRevision': $delete = $wgRequest->getText('wpDelete'); $revisions = explode("\n", $delete); $wgOut->addWikiMsg('maintenance-revdelete', implode(', ', $revisions), wfWikiID()); $affected = 0; // Switch the user here from the current user to Delete page script $OldUser = $wgUser; $wgUser = User::newFromName('Delete page script'); $dbw = wfGetDB(DB_MASTER); foreach ($revisions as $revID) { $dbw->insertSelect('archive', array('page', 'revision'), array('ar_namespace' => 'page_namespace', 'ar_title' => 'page_title', 'ar_comment' => 'rev_comment', 'ar_user' => 'rev_user', 'ar_user_text' => 'rev_user_text', 'ar_timestamp' => 'rev_timestamp', 'ar_minor_edit' => 'rev_minor_edit', 'ar_rev_id' => 'rev_id', 'ar_text_id' => 'rev_text_id'), array('rev_id' => $revID, 'page_id = rev_page'), __METHOD__); if (!$dbw->affectedRows()) { $wgOut->addWikiMsg('maintenance-revnotfound', array($revID)); } else { $affected += $dbw->affectedRows(); $dbw->delete('revision', array('rev_id' => $revID)); } } // ...and switch user back to the old user $wgUser = $OldUser; $wgOut->addWikiMsg('maintenance-success', $type); break; case 'purgeDeletedText': # Data should come off the master, wrapped in a transaction $dbw = wfGetDB(DB_MASTER); $dbw->begin(); # compute table names $tbl_arc = $dbw->tableName('archive'); $tbl_rev = $dbw->tableName('revision'); $tbl_txt = $dbw->tableName('text'); # Delete as appropriate $dbw->query("TRUNCATE TABLE {$tbl_arc}"); // list of "valid" text ids $new_ids = array(); $new_start = 0; // list of "existing" text ids $old_ids = array(); $old_start = 0; // index id $id = 1; // list of ids to be deleted $del_ids = array(); while ($id > 0 && count($del_ids) < 1000) { // get some new "valid" text ids if (count($new_ids) == 0) { $res = $dbw->query("SELECT DISTINCTROW rev_text_id FROM {$tbl_rev} ORDER BY rev_text_id ASC LIMIT {$new_start},100"); while ($row = $dbw->fetchObject($res)) { $new_ids[$row->rev_text_id] = $row->rev_text_id; } if (count($new_ids) == 0) { $id = 0; } else { $new_start += count($new_ids); } } // get some new "existing" text ids if (count($old_ids) == 0) { $res = $dbw->query("SELECT DISTINCTROW old_id FROM {$tbl_txt} ORDER BY old_id ASC LIMIT {$old_start},100"); while ($row = $dbw->fetchObject($res)) { $old_ids[$row->old_id] = $row->old_id; } if (count($old_ids) == 0) { $id = 0; } else { $old_start += count($old_ids); } } // for all ids, check that existing ids are valid while (count($new_ids) > 0 && count($old_ids) > 0) { if (isset($new_ids[$id])) { unset($new_ids[$id]); } else { if (isset($old_ids[$id])) { $del_ids[] = $id; } } unset($old_ids[$id]); $id += 1; } } // print result foreach ($del_ids as $del_id) { $wgOut->addHTML(strval($del_id) . '<br/>'); } // delete rows if (count($del_ids) > 0) { $set = implode(', ', $del_ids); $dbw->query("DELETE FROM {$tbl_txt} WHERE old_id IN ( {$set} )"); } // this solution consummes too much memory //# Get "active" text records from the revisions table //$res = $dbw->query( "SELECT DISTINCTROW rev_text_id FROM $tbl_rev" ); //while( $row = $dbw->fetchObject( $res ) ) { // $cur[] = $row->rev_text_id; //} //# Get the IDs of all text records not in these sets //$set = implode( ', ', $cur ); //$res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" ); //$old = array(); //while( $row = $dbw->fetchObject( $res ) ) { // $old[] = $row->old_id; //} //$count = count( $old ); //# Delete as appropriate //if( $count ) { // $set = implode( ', ', $old ); // $dbw->query( "DELETE FROM $tbl_txt WHERE old_id IN ( $set )" ); //} // this solution is too slow //$res = $dbw->query( "SELECT DISTINCTROW old_id FROM $tbl_txt WHERE NOT EXISTS (SELECT * FROM $tbl_rev WHERE $tbl_rev.rev_text_id = $tbl_txt.old_id)" ); //while( $row = $dbw->fetchObject( $res ) ) { // $old_id = $row->old_id; // $wgOut->addHTML( strval($old_id).'<br/>' ); //} # done $dbw->commit(); $wgOut->addWikiMsg('maintenance-success', $type); break; case 'eval': $temp = error_reporting(E_ALL); ob_start(); $str = eval($wgRequest->getText('wpCode', 'return;')); $ext = ob_get_clean(); error_reporting(0); if ($ext) { $wgOut->addHTML(nl2br($ext) . '<hr />'); } if (!$str) { // do nothing } elseif (is_string($str)) { $wgOut->addHTML(nl2br($str) . '<hr />'); } else { $wgOut->addHTML(nl2br(var_export($str, true)) . '<hr />'); } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'initEditCount': global $wgDBservers; $dbw = wfGetDB(DB_MASTER); $user = $dbw->tableName('user'); $revision = $dbw->tableName('revision'); $dbver = $dbw->getServerVersion(); $dbr = wfGetDB(DB_SLAVE); $chunkSize = 100; $lastUser = $dbr->selectField('user', 'MAX(user_id)', '', __FUNCTION__); $start = microtime(true); $migrated = 0; for ($min = 0; $min <= $lastUser; $min += $chunkSize) { $max = $min + $chunkSize; $result = $dbr->query("SELECT\r\n\t\t\t\t\t\t\tuser_id,\r\n\t\t\t\t\t\t\tCOUNT(rev_user) AS user_editcount\r\n\t\t\t\t\t\tFROM {$user}\r\n\t\t\t\t\t\tLEFT OUTER JOIN {$revision} ON user_id=rev_user\r\n\t\t\t\t\t\tWHERE user_id > {$min} AND user_id <= {$max}\r\n\t\t\t\t\t\tGROUP BY user_id", 'initEditCount'); while ($row = $dbr->fetchObject($result)) { $dbw->update('user', array('user_editcount' => $row->user_editcount), array('user_id' => $row->user_id), 'initEditCount'); ++$migrated; } $dbr->freeResult($result); waitForSlaves(10); } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'initStats': $dbr = wfGetDB(DB_SLAVE); $edits = $dbr->selectField('revision', 'COUNT(*)', '', __METHOD__); $edits += $dbr->selectField('archive', 'COUNT(*)', '', __METHOD__); $wgOut->addWikiMsg('maintenance-stats-edits', $edits); global $wgContentNamespaces; $good = $dbr->selectField('page', 'COUNT(*)', array('page_namespace' => $wgContentNamespaces, 'page_is_redirect' => 0, 'page_len > 0'), __METHOD__); $wgOut->addWikiMsg('maintenance-stats-articles', $good); $pages = $dbr->selectField('page', 'COUNT(*)', '', __METHOD__); $wgOut->addWikiMsg('maintenance-stats-pages', $pages); $users = $dbr->selectField('user', 'COUNT(*)', '', __METHOD__); $wgOut->addWikiMsg('maintenance-stats-users', $users); $admin = $dbr->selectField('user_groups', 'COUNT(*)', array('ug_group' => 'sysop'), __METHOD__); $wgOut->addWikiMsg('maintenance-stats-admins', $admin); $image = $dbr->selectField('image', 'COUNT(*)', '', __METHOD__); $wgOut->addWikiMsg('maintenance-stats-images', $image); if (!$wgRequest->getCheck('wpNoview')) { $views = $dbr->selectField('page', 'SUM(page_counter)', '', __METHOD__); $wgOut->addWikiMsg('maintenance-stats-views', $views); } $wgOut->addWikiMsg('maintenance-stats-update'); $dbw = wfGetDB(DB_MASTER); $values = array('ss_total_edits' => $edits, 'ss_good_articles' => $good, 'ss_total_pages' => $pages, 'ss_users' => $users, 'ss_admins' => $admin, 'ss_images' => $image); $conds = array('ss_row_id' => 1); $views = array('ss_total_views' => isset($views) ? $views : 0); if ($wgRequest->getCheck('wpUpdate')) { $dbw->update('site_stats', $values, $conds, __METHOD__); } else { $dbw->delete('site_stats', $conds, __METHOD__); $dbw->insert('site_stats', array_merge($values, $conds, $views), __METHOD__); } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'moveBatch': $reason = $wgRequest->getText('wpReason', ''); $interval = 0; $pages = $wgRequest->getText('wpMove'); $dbw = wfGetDB(DB_MASTER); $lines = explode("\n", $pages); foreach ($lines as $line) { $parts = array_map('trim', explode('|', $line)); if (count($parts) != 2) { continue; } $source = Title::newFromText($parts[0]); $dest = Title::newFromText($parts[1]); if (is_null($source) || is_null($dest)) { continue; } $wgOut->addWikiText('* ' . wfMsg('maintenance-move', array($source->getPrefixedText(), $dest->getPrefixedText()))); $dbw->begin(); $err = $source->moveTo($dest, false, $reason); if ($err !== true) { $wgOut->addWikiText('** ' . wfMsg('maintenance-movefail', array($err))); } $dbw->commit(); waitForSlaves(5); } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'reassignEdits': $wpFrom = $wgRequest->getVal('wpFrom'); $wpTo = $wgRequest->getVal('wpTo'); if (User::isIP($wpFrom)) { $from = new User(); $from->setId(0); $from->setName($wpFrom); } else { $from = User::newFromName($wpFrom); } if (User::isIP($wpTo)) { $to = new User(); $to->setId(0); $to->setName($wpTo); } else { $to = User::newFromName($wpTo); } if ($to->getId() || $wgRequest->getCheck('wpForce')) { $report = $wgRequest->getCheck('wpReport'); $dbw = wfGetDB(DB_MASTER); $dbw->immediateBegin(); $rcond = $from->getId() ? array('rev_user' => $from->getId()) : array('rev_user_text' => $from->getName()); $res = $dbw->select('revision', 'COUNT(*) AS count', $rcond, 'Maintenance::reassignEdits'); $row = $dbw->fetchObject($res); $cur = $row->count; $wgOut->addWikiMsg('maintenance-re-ce', $cur); $acond = $from->getId() ? array('ar_user' => $from->getId()) : array('ar_user_text' => $from->getName()); $res = $dbw->select('archive', 'COUNT(*) AS count', $acond, 'Maintenance::reassignEdits'); $row = $dbw->fetchObject($res); $del = $row->count; $wgOut->addWikiMsg('maintenance-re-de', $del); if (!$wgRequest->getCheck('wpRc')) { $ccond = $from->getId() ? array('rc_user' => $from->getId()) : array('rc_user_text' => $from->getName()); $res = $dbw->select('recentchanges', 'COUNT(*) AS count', $ccond, 'Maintenance::reassignEdits'); $row = $dbw->fetchObject($res); $rec = $row->count; $wgOut->addWikiMsg('maintenance-re-rce', $rec); } else { $rec = 0; } $total = $cur + $del + $rec; $wgOut->addWikiMsg('maintenance-re-total', $total); if (!$report) { $rspec = array('rev_user' => $to->getId(), 'rev_user_text' => $to->getName()); $res = $dbw->update('revision', $rspec, $rcond, 'Maintenance::reassignEdits'); $aspec = array('ar_user' => $to->getId(), 'ar_user_text' => $to->getName()); $res = $dbw->update('archive', $aspec, $acond, 'Maintenance::reassignEdits'); if (!$wgRequest->getCheck('wpRc')) { $cspec = array('rc_user' => $to->getId(), 'rc_user_text' => $to->getName()); $res = $dbw->update('recentchanges', $cspec, $ccond, 'Maintenance::reassignEdits'); } } $dbw->immediateCommit(); if ($report) { $wgOut->addWikiMsg('maintenance-re-rr', wfMsg('maintenance-re-report')); } } else { $ton = $to->getName(); $wgOut->addWikiMsg('maintenance-re-nf', $ton); } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'runJobs': $maxJobs = 10000; $dbw = wfGetDB(DB_MASTER); $n = 0; while ($dbw->selectField('job', 'count(*)', '', 'runJobs.php')) { $offset = 0; for (;;) { $job = Job::pop($offset); if ($job == false) { break; } waitForSlaves(5); $wgOut->addWikiText("* " . $job->id . " " . $job->toString()); $offset = $job->id; if (!$job->run()) { $wgOut->addWikiText("** " . wfMsg('maintenance-error', array($job->error))); } if ($maxJobs && ++$n > $maxJobs) { break 2; } } } $wgOut->addWikiMsg('maintenance-success', $type); break; case 'showJobs': $dbw = wfGetDB(DB_MASTER); $count = $dbw->selectField('job', 'count(*)', '', 'runJobs.php'); $wgOut->addHTML($count); $wgOut->addWikiMsg('maintenance-success', $type); break; case 'stats': global $wgMemc; if (get_class($wgMemc) == 'FakeMemCachedClient') { $wgOut->addWikiMsg('maintenance-memc-fake'); return; } $wgOut->addWikiText('<h2>' . wfMsg('maintenance-memc-requests') . '</h2>'); $session = intval($wgMemc->get(wfMemcKey('stats', 'request_with_session'))); $noSession = intval($wgMemc->get(wfMemcKey('stats', 'request_without_session'))); $total = $session + $noSession; $requests = sprintf(wfMsg('maintenance-memc-withsession') . " %-10d %6.2f%%\n", $session, $session / $total * 100) . '<br />'; $requests .= sprintf(wfMsg('maintenance-memc-withoutsession') . " %-10d %6.2f%%\n", $noSession, $noSession / $total * 100) . '<br />'; $requests .= sprintf(wfMsg('maintenance-memc-total') . " %-10d %6.2f%%\n", $total, 100) . '<br />'; $wgOut->addWikiText($requests); $wgOut->addWikiText('<h2>' . wfMsg('maintenance-memc-parsercache') . '</h2>'); $hits = intval($wgMemc->get(wfMemcKey('stats', 'pcache_hit'))); $invalid = intval($wgMemc->get(wfMemcKey('stats', 'pcache_miss_invalid'))); $expired = intval($wgMemc->get(wfMemcKey('stats', 'pcache_miss_expired'))); $absent = intval($wgMemc->get(wfMemcKey('stats', 'pcache_miss_absent'))); $stub = intval($wgMemc->get(wfMemcKey('stats', 'pcache_miss_stub'))); $total = $hits + $invalid + $expired + $absent + $stub; $pcache = sprintf(wfMsg('maintenance-memc-hits') . " %-10d %6.2f%%\n", $hits, $hits / $total * 100) . '<br />'; $pcache .= sprintf(wfMsg('maintenance-memc-invalid') . " %-10d %6.2f%%\n", $invalid, $invalid / $total * 100) . '<br />'; $pcache .= sprintf(wfMsg('maintenance-memc-expired') . " %-10d %6.2f%%\n", $expired, $expired / $total * 100) . '<br />'; $pcache .= sprintf(wfMsg('maintenance-memc-absent') . " %-10d %6.2f%%\n", $absent, $absent / $total * 100) . '<br />'; $pcache .= sprintf(wfMsg('maintenance-memc-stub') . " %-10d %6.2f%%\n", $stub, $stub / $total * 100) . '<br />'; $pcache .= sprintf(wfMsg('maintenance-memc-total') . " %-10d %6.2f%%\n", $total, 100) . '<br />'; $wgOut->addWikiText($pcache); $hits = intval($wgMemc->get(wfMemcKey('stats', 'image_cache_hit'))); $misses = intval($wgMemc->get(wfMemcKey('stats', 'image_cache_miss'))); $updates = intval($wgMemc->get(wfMemcKey('stats', 'image_cache_update'))); $total = $hits + $misses; $wgOut->addWikiText('<h2>' . wfMsg('maintenance-memc-imagecache') . '</h2>'); $icache = sprintf(wfMsg('maintenance-memc-hits') . " %-10d %6.2f%%\n", $hits, $hits / $total * 100) . '<br />'; $icache .= sprintf(wfMsg('maintenance-memc-misses') . " %-10d %6.2f%%\n", $misses, $misses / $total * 100) . '<br />'; $icache .= sprintf(wfMsg('maintenance-memc-updates') . " %-10d\n", $updates) . '<br />'; $wgOut->addWikiText($icache); $hits = intval($wgMemc->get(wfMemcKey('stats', 'diff_cache_hit'))); $misses = intval($wgMemc->get(wfMemcKey('stats', 'diff_cache_miss'))); $uncacheable = intval($wgMemc->get(wfMemcKey('stats', 'diff_uncacheable'))); $total = $hits + $misses + $uncacheable; $wgOut->addWikiText('<h2>' . wfMsg('maintenance-memc-diffcache') . '</h2>'); $dcache = sprintf(wfMsg('maintenance-memc-hits') . " %-10d %6.2f%%\n", $hits, $hits / $total * 100) . '<br />'; $dcache .= sprintf(wfMsg('maintenance-memc-misses') . " %-10d %6.2f%%\n", $misses, $misses / $total * 100) . '<br />'; $dcache .= sprintf(wfMsg('maintenance-memc-uncacheable') . " %-10d %6.2f%%\n", $uncacheable, $uncacheable / $total * 100) . '<br />'; $wgOut->addWikiText($dcache); $wgOut->addWikiMsg('maintenance-success', $type); break; case 'sql': $db = wfGetDB(DB_MASTER); $q = $wgRequest->getText('wpQuery', ''); $db->begin(); try { $r = $db->query($q, 'Maintenance::sql.php'); } catch (DBQueryError $e) { global $wgShowSQLErrors; $temp = $wgShowSQLErrors; $wgShowSQLErrors = true; $wgOut->addWikiText('<pre style="overflow: auto">' . $e->getText() . '</pre>'); $wgShowSQLErrors = $temp; $r = false; } if ($r === true) { $wgOut->addWikiMsg('maintenance-sql-aff', $db->affectedRows()); } elseif ($r instanceof ResultWrapper) { $res = array(); for ($i = 0; $i < $r->numRows(); $i++) { $row = $r->fetchRow(); $res[] = $row; foreach ($row as $key => $meh) { $names[] = $key; } } $names = array_unique($names); $rtable = '<table class="wikitable"><tr>'; foreach ($names as $name) { if (is_numeric($name)) { continue; } $rtable .= '<th>' . $name . '</th>'; } $rtable .= '</tr>'; foreach ($res as $data) { $rtable .= '<tr>'; foreach ($data as $key => $value) { if (is_numeric($key)) { continue; } $rtable .= '<td><nowiki>' . $value . '</nowiki></td>'; } $rtable .= '</tr>'; } $rtable .= '</table>'; $wgOut->addWikiMsg('maintenance-sql-res', $r->numRows(), $rtable); $db->freeResult($r); } $db->commit(); $wgOut->addWikiMsg('maintenance-success', $type); break; default: $wgOut->addWikiMsg('maintenance-invalidtype'); return; } }
$maxJobs = 10000; } $type = false; if (isset($options['type'])) { $type = $options['type']; } $wgTitle = Title::newFromText('RunJobs.php'); $dbw = wfGetDB(DB_MASTER); $n = 0; $conds = ''; if ($type !== false) { $conds = "job_cmd = " . $dbw->addQuotes($type); } while ($dbw->selectField('job', 'job_id', $conds, 'runJobs.php')) { $offset = 0; for (;;) { $job = $type == false ? Job::pop($offset) : Job::pop_type($type); if ($job == false) { break; } wfWaitForSlaves(5); print wfTimestamp(TS_DB) . " " . $job->id . " " . $job->toString() . "\n"; $offset = $job->id; if (!$job->run()) { print wfTimestamp(TS_DB) . " Error: {$job->error}\n"; } if ($maxJobs && ++$n > $maxJobs) { break 2; } } }