From 4c54454be48908c89c89c3d074382ff0baed33be Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Thu, 11 Apr 2013 14:08:45 -0700 Subject: [PATCH] Moved ChronologyProtector to its own file. Change-Id: I01bf0206322454e36633921887d10356a48ab5cb --- includes/AutoLoader.php | 2 +- includes/db/ChronologyProtector.php | 95 +++++++++++++++++++++++++++++ includes/db/LBFactory.php | 73 ---------------------- 3 files changed, 96 insertions(+), 74 deletions(-) create mode 100644 includes/db/ChronologyProtector.php diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 7d6b8327e1..aaea94944d 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -471,7 +471,7 @@ $wgAutoloadLocalClasses = array( # includes/db 'Blob' => 'includes/db/DatabaseUtility.php', - 'ChronologyProtector' => 'includes/db/LBFactory.php', + 'ChronologyProtector' => 'includes/db/ChronologyProtector.php', 'CloneDatabase' => 'includes/db/CloneDatabase.php', 'DatabaseBase' => 'includes/db/Database.php', 'DatabaseMssql' => 'includes/db/DatabaseMssql.php', diff --git a/includes/db/ChronologyProtector.php b/includes/db/ChronologyProtector.php new file mode 100644 index 0000000000..447b238ff9 --- /dev/null +++ b/includes/db/ChronologyProtector.php @@ -0,0 +1,95 @@ +startupPos === null ) { + if ( !empty( $_SESSION[__CLASS__] ) ) { + $this->startupPos = $_SESSION[__CLASS__]; + } + } + if ( !$this->startupPos ) { + return; + } + $masterName = $lb->getServerName( 0 ); + + if ( $lb->getServerCount() > 1 && !empty( $this->startupPos[$masterName] ) ) { + $info = $lb->parentInfo(); + $pos = $this->startupPos[$masterName]; + wfDebug( __METHOD__ . ": LB " . $info['id'] . " waiting for master pos $pos\n" ); + $lb->waitFor( $this->startupPos[$masterName] ); + } + } + + /** + * Notify the ChronologyProtector that the LoadBalancer is about to shut + * down. Saves replication positions. + * + * @param $lb LoadBalancer + */ + function shutdownLB( $lb ) { + // Don't start a session, don't bother with non-replicated setups + if ( strval( session_id() ) == '' || $lb->getServerCount() <= 1 ) { + return; + } + $masterName = $lb->getServerName( 0 ); + if ( isset( $this->shutdownPos[$masterName] ) ) { + // Already done + return; + } + // Only save the position if writes have been done on the connection + $db = $lb->getAnyOpenConnection( 0 ); + $info = $lb->parentInfo(); + if ( !$db || !$db->doneWrites() ) { + wfDebug( __METHOD__ . ": LB {$info['id']}, no writes done\n" ); + return; + } + $pos = $db->getMasterPos(); + wfDebug( __METHOD__ . ": LB {$info['id']} has master pos $pos\n" ); + $this->shutdownPos[$masterName] = $pos; + } + + /** + * Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now. + * May commit chronology data to persistent storage. + */ + function shutdown() { + if ( session_id() != '' && count( $this->shutdownPos ) ) { + wfDebug( __METHOD__ . ": saving master pos for " . + count( $this->shutdownPos ) . " master(s)\n" ); + $_SESSION[__CLASS__] = $this->shutdownPos; + } + } +} diff --git a/includes/db/LBFactory.php b/includes/db/LBFactory.php index 85e7775dbd..1fcc69a6ee 100644 --- a/includes/db/LBFactory.php +++ b/includes/db/LBFactory.php @@ -317,76 +317,3 @@ class DBAccessError extends MWException { parent::__construct( "Mediawiki tried to access the database via wfGetDB(). This is not allowed." ); } } - -/** - * Class for ensuring a consistent ordering of events as seen by the user, despite replication. - * Kind of like Hawking's [[Chronology Protection Agency]]. - */ -class ChronologyProtector { - var $startupPos; - var $shutdownPos = array(); - - /** - * Initialise a LoadBalancer to give it appropriate chronology protection. - * - * @param $lb LoadBalancer - */ - function initLB( $lb ) { - if ( $this->startupPos === null ) { - if ( !empty( $_SESSION[__CLASS__] ) ) { - $this->startupPos = $_SESSION[__CLASS__]; - } - } - if ( !$this->startupPos ) { - return; - } - $masterName = $lb->getServerName( 0 ); - - if ( $lb->getServerCount() > 1 && !empty( $this->startupPos[$masterName] ) ) { - $info = $lb->parentInfo(); - $pos = $this->startupPos[$masterName]; - wfDebug( __METHOD__ . ": LB " . $info['id'] . " waiting for master pos $pos\n" ); - $lb->waitFor( $this->startupPos[$masterName] ); - } - } - - /** - * Notify the ChronologyProtector that the LoadBalancer is about to shut - * down. Saves replication positions. - * - * @param $lb LoadBalancer - */ - function shutdownLB( $lb ) { - // Don't start a session, don't bother with non-replicated setups - if ( strval( session_id() ) == '' || $lb->getServerCount() <= 1 ) { - return; - } - $masterName = $lb->getServerName( 0 ); - if ( isset( $this->shutdownPos[$masterName] ) ) { - // Already done - return; - } - // Only save the position if writes have been done on the connection - $db = $lb->getAnyOpenConnection( 0 ); - $info = $lb->parentInfo(); - if ( !$db || !$db->doneWrites() ) { - wfDebug( __METHOD__ . ": LB {$info['id']}, no writes done\n" ); - return; - } - $pos = $db->getMasterPos(); - wfDebug( __METHOD__ . ": LB {$info['id']} has master pos $pos\n" ); - $this->shutdownPos[$masterName] = $pos; - } - - /** - * Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now. - * May commit chronology data to persistent storage. - */ - function shutdown() { - if ( session_id() != '' && count( $this->shutdownPos ) ) { - wfDebug( __METHOD__ . ": saving master pos for " . - count( $this->shutdownPos ) . " master(s)\n" ); - $_SESSION[__CLASS__] = $this->shutdownPos; - } - } -} -- 2.20.1