X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2FMediaWiki.php;h=6c932d2a2e2561c53b5493d9b61cdc6258a246a4;hp=beb9de5d215636aec08d9dfe96cc4c96564d9475;hb=f4ec592330517bc80e2ee351d0385e752f16e3fb;hpb=336454104d1249439e3ff97746de69c5e7b4a5f9 diff --git a/includes/MediaWiki.php b/includes/MediaWiki.php index beb9de5d21..6c932d2a2e 100644 --- a/includes/MediaWiki.php +++ b/includes/MediaWiki.php @@ -548,6 +548,9 @@ class MediaWiki { } } + MWExceptionHandler::handleException( $e ); + } catch ( Error $e ) { + // Type errors and such: at least handle it now and clean up the LBFactory state MWExceptionHandler::handleException( $e ); } @@ -603,50 +606,54 @@ class MediaWiki { DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND ); wfDebug( __METHOD__ . ': pre-send deferred updates completed' ); - // Decide when clients block on ChronologyProtector DB position writes - $urlDomainDistance = ( - $request->wasPosted() && - $output->getRedirect() && - $lbFactory->hasOrMadeRecentMasterChanges( INF ) - ) ? self::getUrlDomainDistance( $output->getRedirect() ) : false; + // Should the client return, their request should observe the new ChronologyProtector + // DB positions. This request might be on a foreign wiki domain, so synchronously update + // the DB positions in all datacenters to be safe. If this output is not a redirect, + // then OutputPage::output() will be relatively slow, meaning that running it in + // $postCommitWork should help mask the latency of those updates. + $flags = $lbFactory::SHUTDOWN_CHRONPROT_SYNC; + $strategy = 'cookie+sync'; $allowHeaders = !( $output->isDisabled() || headers_sent() ); - if ( $urlDomainDistance === 'local' || $urlDomainDistance === 'remote' ) { - // OutputPage::output() will be fast; $postCommitWork will not be useful for - // masking the latency of syncing DB positions accross all datacenters synchronously. - // Instead, make use of the RTT time of the client follow redirects. - $flags = $lbFactory::SHUTDOWN_CHRONPROT_ASYNC; - $cpPosTime = microtime( true ); - // Client's next request should see 1+ positions with this DBMasterPos::asOf() time - if ( $urlDomainDistance === 'local' && $allowHeaders ) { - // Client will stay on this domain, so set an unobtrusive cookie - $expires = time() + ChronologyProtector::POSITION_TTL; - $options = [ 'prefix' => '' ]; - $request->response()->setCookie( 'cpPosTime', $cpPosTime, $expires, $options ); - } else { - // Cookies may not work across wiki domains, so use a URL parameter - $safeUrl = $lbFactory->appendPreShutdownTimeAsQuery( - $output->getRedirect(), - $cpPosTime - ); - $output->redirect( $safeUrl ); + if ( $output->getRedirect() && $lbFactory->hasOrMadeRecentMasterChanges( INF ) ) { + // OutputPage::output() will be fast, so $postCommitWork is useless for masking + // the latency of synchronously updating the DB positions in all datacenters. + // Try to make use of the time the client spends following redirects instead. + $domainDistance = self::getUrlDomainDistance( $output->getRedirect() ); + if ( $domainDistance === 'local' && $allowHeaders ) { + $flags = $lbFactory::SHUTDOWN_CHRONPROT_ASYNC; + $strategy = 'cookie'; // use same-domain cookie and keep the URL uncluttered + } elseif ( $domainDistance === 'remote' ) { + $flags = $lbFactory::SHUTDOWN_CHRONPROT_ASYNC; + $strategy = 'cookie+url'; // cross-domain cookie might not work } - } else { - // OutputPage::output() is fairly slow; run it in $postCommitWork to mask - // the latency of syncing DB positions accross all datacenters synchronously - $flags = $lbFactory::SHUTDOWN_CHRONPROT_SYNC; - if ( $lbFactory->hasOrMadeRecentMasterChanges( INF ) && $allowHeaders ) { - $cpPosTime = microtime( true ); - // Set a cookie in case the DB position store cannot sync accross datacenters. - // This will at least cover the common case of the user staying on the domain. + } + + // Record ChronologyProtector positions for DBs affected in this request at this point + $cpIndex = null; + $lbFactory->shutdown( $flags, $postCommitWork, $cpIndex ); + wfDebug( __METHOD__ . ': LBFactory shutdown completed' ); + + if ( $cpIndex > 0 ) { + if ( $allowHeaders ) { $expires = time() + ChronologyProtector::POSITION_TTL; $options = [ 'prefix' => '' ]; - $request->response()->setCookie( 'cpPosTime', $cpPosTime, $expires, $options ); + $request->response()->setCookie( 'cpPosIndex', $cpIndex, $expires, $options ); + } + + if ( $strategy === 'cookie+url' ) { + if ( $output->getRedirect() ) { // sanity + $safeUrl = $lbFactory->appendShutdownCPIndexAsQuery( + $output->getRedirect(), + $cpIndex + ); + $output->redirect( $safeUrl ); + } else { + $e = new LogicException( "No redirect; cannot append cpPosIndex parameter." ); + MWExceptionHandler::logException( $e ); + } } } - // Record ChronologyProtector positions for DBs affected in this request at this point - $lbFactory->shutdown( $flags, $postCommitWork ); - wfDebug( __METHOD__ . ': LBFactory shutdown completed' ); // Set a cookie to tell all CDN edge nodes to "stick" the user to the DC that handles this // POST request (e.g. the "master" data center). Also have the user briefly bypass CDN so @@ -727,10 +734,12 @@ class MediaWiki { if ( function_exists( 'register_postsend_function' ) ) { // https://github.com/facebook/hhvm/issues/1230 register_postsend_function( $callback ); + /** @noinspection PhpUnusedLocalVariableInspection */ $blocksHttpClient = false; } else { if ( function_exists( 'fastcgi_finish_request' ) ) { fastcgi_finish_request(); + /** @noinspection PhpUnusedLocalVariableInspection */ $blocksHttpClient = false; } else { // Either all DB and deferred updates should happen or none. @@ -1022,7 +1031,7 @@ class MediaWiki { $port = $info['port']; } - MediaWiki\suppressWarnings(); + Wikimedia\suppressWarnings(); $sock = $host ? fsockopen( $host, $port, @@ -1031,7 +1040,7 @@ class MediaWiki { // If it takes more than 100ms to connect to ourselves there is a problem... 0.100 ) : false; - MediaWiki\restoreWarnings(); + Wikimedia\restoreWarnings(); $invokedWithSuccess = true; if ( $sock ) {