ttmserver-export.php

Go to the documentation of this file.
00001 <?php
00010 // Standard boilerplate to define $IP
00011 if ( getenv( 'MW_INSTALL_PATH' ) !== false ) {
00012     $IP = getenv( 'MW_INSTALL_PATH' );
00013 } else {
00014     $dir = __DIR__;
00015     $IP = "$dir/../../..";
00016 }
00017 require_once "$IP/maintenance/Maintenance.php";
00018 
00023 class TTMServerBootstrap extends Maintenance {
00025     protected $config;
00026 
00027     public function __construct() {
00028         parent::__construct();
00029         $this->mDescription = 'Script to bootstrap TTMServer.';
00030         $this->addOption(
00031             'threads',
00032             '(optional) Number of threads',
00033             /*required*/false,
00034             /*has arg*/true
00035         );
00036         $this->addOption(
00037             'ttmserver',
00038             '(optional) Server configuration identifier',
00039             /*required*/false,
00040             /*has arg*/true
00041         );
00042         $this->setBatchSize( 500 );
00043         $this->start = microtime( true );
00044     }
00045 
00046     protected function statusLine( $text, $channel = null ) {
00047         $pid = sprintf( "%5s", getmypid() );
00048         $prefix = sprintf( "%6.2f", microtime( true ) - $this->start );
00049         $mem = sprintf( "%5.1fM", ( memory_get_usage( true ) / ( 1024 * 1024 ) ) );
00050         $this->output( "$pid $prefix $mem  $text", $channel );
00051     }
00052 
00053     public function execute() {
00054         global $wgTranslateTranslationServices;
00055 
00056         // TTMServer is the id of the enabled-by-default instance
00057         $configKey = $this->getOption( 'ttmserver', 'TTMServer' );
00058         if ( !isset( $wgTranslateTranslationServices[$configKey] ) ) {
00059             $this->error( "Translation memory is not configured properly", 1 );
00060         }
00061 
00062         $this->config = $config = $wgTranslateTranslationServices[$configKey];
00063         $server = TTMServer::factory( $config );
00064 
00065         $this->statusLine( "Loading groups...\n" );
00066         $groups = MessageGroups::singleton()->getGroups();
00067 
00068         $threads = $this->getOption( 'threads', 1 );
00069         $pids = array();
00070 
00071         $this->statusLine( "Cleaning up old entries...\n" );
00072         $server->beginBootstrap();
00073 
00074         foreach ( $groups as $id => $group ) {
00078             if ( $group->isMeta() ) {
00079                 continue;
00080             }
00081 
00082             // Fork to avoid unbounded memory usage growth
00083             $pid = pcntl_fork();
00084 
00085             if ( $pid === 0 ) {
00086                 // Child, reseed because there is no bug in PHP:
00087                 // http://bugs.php.net/bug.php?id=42465
00088                 mt_srand( getmypid() );
00089 
00090                 // Make sure all existing connections are dead,
00091                 // we can't use them in forked children.
00092                 LBFactory::destroyInstance();
00093 
00094                 $this->exportGroup( $group );
00095                 exit();
00096             } elseif ( $pid === -1 ) {
00097                 // Fork failed do it serialized
00098                 $this->exportGroup( $group );
00099             } else {
00100                 $this->statusLine( "Forked thread $pid to handle $id\n" );
00101                 $pids[$pid] = true;
00102 
00103                 // If we hit the thread limit, wait for any child to finish.
00104                 if ( count( $pids ) >= $threads ) {
00105                     $status = 0;
00106                     $pid = pcntl_wait( $status );
00107                     unset( $pids[$pid] );
00108                 }
00109             }
00110         }
00111 
00112         // Return control after all threads have finished.
00113         foreach ( array_keys( $pids ) as $pid ) {
00114             $status = 0;
00115             pcntl_waitpid( $pid, $status );
00116         }
00117 
00118         $this->statusLine( "Creating indexes and optimizing...\n" );
00119         $server->endBootstrap();
00120     }
00121 
00122     protected function exportGroup( MessageGroup $group ) {
00123         $server = TTMServer::factory( $this->config );
00124 
00125         $id = $group->getId();
00126         $sourceLanguage = $group->getSourceLanguage();
00127 
00128         $stats = MessageGroupStats::forGroup( $id );
00129 
00130         $collection = $group->initCollection( $sourceLanguage );
00131         $collection->filter( 'ignored' );
00132         $collection->initMessages();
00133 
00134         $server->beginBatch();
00135         $inserts = array();
00136 
00137         foreach ( $collection->keys() as $mkey => $title ) {
00138             $def = $collection[$mkey]->definition();
00139             $inserts[$mkey] = array( $title, $sourceLanguage, $def );
00140         }
00141 
00142         do {
00143             $batch = array_splice( $inserts, 0, $this->mBatchSize );
00144             $server->batchInsertDefinitions( $batch );
00145         } while ( count( $inserts ) );
00146 
00147         $inserts = array();
00148         foreach ( $stats as $targetLanguage => $numbers ) {
00149             if ( $targetLanguage === $sourceLanguage ) {
00150                 continue;
00151             }
00152             if ( $numbers[MessageGroupStats::TRANSLATED] === 0 ) {
00153                 continue;
00154             }
00155 
00156             $collection->resetForNewLanguage( $targetLanguage );
00157             $collection->filter( 'ignored' );
00158             $collection->filter( 'translated', false );
00159             $collection->loadTranslations();
00160 
00161             foreach ( $collection->keys() as $mkey => $title ) {
00162                 $inserts[$mkey] = array( $title, $targetLanguage, $collection[$mkey]->translation() );
00163             }
00164 
00165             do {
00166                 $batch = array_splice( $inserts, 0, $this->mBatchSize );
00167                 $server->batchInsertTranslations( $batch );
00168             } while ( count( $inserts ) );
00169         }
00170 
00171         $server->endBatch();
00172     }
00173 }
00174 
00175 $maintClass = 'TTMServerBootstrap';
00176 require_once RUN_MAINTENANCE_IF_MAIN;
Generated on Tue Oct 29 00:00:24 2013 for MediaWiki Translate Extension by  doxygen 1.6.3