aboutsummaryrefslogtreecommitdiffstats
path: root/includes/MessageBlobStore.php
diff options
context:
space:
mode:
authorCatrope <roan.kattouw@gmail.com>2013-01-15 15:32:10 -0800
committerGerrit Code Review <gerrit@wikimedia.org>2013-01-16 03:10:26 +0000
commite2e8461fd23d81aa3c89a56245053c6d3f06da84 (patch)
treef2fb568eee213fc01820e54c43ac2e4c9e9ce35a /includes/MessageBlobStore.php
parentab8de17e0f7bc40eecee7d9e32cd0ccd9e783610 (diff)
downloadmediawikicore-e2e8461fd23d81aa3c89a56245053c6d3f06da84.tar.gz
mediawikicore-e2e8461fd23d81aa3c89a56245053c6d3f06da84.zip
(bug 31044) Make ResourceLoader behave in read-only mode
When the database is in read-only mode or writes fail for some other reason, ResourceLoader should make every attempt to still serve JS and CSS correctly. * Surround a bunch of DB write code in MessageBlobStore.php in try-catch blocks. * Surround the DB write in ResourceLoaderFileModule.php in a try-catch block rather than checking wfReadOnly(), because the DB may fail for other reasons. * In ResourceLoader::respond() and helpers, set a short cache timeout on responses that include commented-out error messages. Change-Id: Idc83a0fe042806263f9337c40ade8c38c56aa3cd
Diffstat (limited to 'includes/MessageBlobStore.php')
-rw-r--r--includes/MessageBlobStore.php218
1 files changed, 116 insertions, 102 deletions
diff --git a/includes/MessageBlobStore.php b/includes/MessageBlobStore.php
index 09561bd78ae7..6322be7565b3 100644
--- a/includes/MessageBlobStore.php
+++ b/includes/MessageBlobStore.php
@@ -80,42 +80,45 @@ class MessageBlobStore {
return false;
}
- $dbw = wfGetDB( DB_MASTER );
- $success = $dbw->insert( 'msg_resource', array(
- 'mr_lang' => $lang,
- 'mr_resource' => $name,
- 'mr_blob' => $blob,
- 'mr_timestamp' => $dbw->timestamp()
- ),
- __METHOD__,
- array( 'IGNORE' )
- );
-
- if ( $success ) {
- if ( $dbw->affectedRows() == 0 ) {
- // Blob was already present, fetch it
- $blob = $dbw->selectField( 'msg_resource', 'mr_blob', array(
- 'mr_resource' => $name,
- 'mr_lang' => $lang,
- ),
- __METHOD__
- );
- } else {
- // Update msg_resource_links
- $rows = array();
+ try {
+ $dbw = wfGetDB( DB_MASTER );
+ $success = $dbw->insert( 'msg_resource', array(
+ 'mr_lang' => $lang,
+ 'mr_resource' => $name,
+ 'mr_blob' => $blob,
+ 'mr_timestamp' => $dbw->timestamp()
+ ),
+ __METHOD__,
+ array( 'IGNORE' )
+ );
- foreach ( $module->getMessages() as $key ) {
- $rows[] = array(
- 'mrl_resource' => $name,
- 'mrl_message' => $key
+ if ( $success ) {
+ if ( $dbw->affectedRows() == 0 ) {
+ // Blob was already present, fetch it
+ $blob = $dbw->selectField( 'msg_resource', 'mr_blob', array(
+ 'mr_resource' => $name,
+ 'mr_lang' => $lang,
+ ),
+ __METHOD__
+ );
+ } else {
+ // Update msg_resource_links
+ $rows = array();
+
+ foreach ( $module->getMessages() as $key ) {
+ $rows[] = array(
+ 'mrl_resource' => $name,
+ 'mrl_message' => $key
+ );
+ }
+ $dbw->insert( 'msg_resource_links', $rows,
+ __METHOD__, array( 'IGNORE' )
);
}
- $dbw->insert( 'msg_resource_links', $rows,
- __METHOD__, array( 'IGNORE' )
- );
}
+ } catch ( Exception $e ) {
+ wfDebug( __METHOD__ . " failed to update DB: $e\n" );
}
-
return $blob;
}
@@ -141,48 +144,51 @@ class MessageBlobStore {
$oldBlob = $row->mr_blob;
$newBlob = self::generateMessageBlob( $module, $lang );
- $newRow = array(
- 'mr_resource' => $name,
- 'mr_lang' => $lang,
- 'mr_blob' => $newBlob,
- 'mr_timestamp' => $dbw->timestamp()
- );
+ try {
+ $newRow = array(
+ 'mr_resource' => $name,
+ 'mr_lang' => $lang,
+ 'mr_blob' => $newBlob,
+ 'mr_timestamp' => $dbw->timestamp()
+ );
- $dbw->replace( 'msg_resource',
- array( array( 'mr_resource', 'mr_lang' ) ),
- $newRow, __METHOD__
- );
+ $dbw->replace( 'msg_resource',
+ array( array( 'mr_resource', 'mr_lang' ) ),
+ $newRow, __METHOD__
+ );
- // Figure out which messages were added and removed
- $oldMessages = array_keys( FormatJson::decode( $oldBlob, true ) );
- $newMessages = array_keys( FormatJson::decode( $newBlob, true ) );
- $added = array_diff( $newMessages, $oldMessages );
- $removed = array_diff( $oldMessages, $newMessages );
+ // Figure out which messages were added and removed
+ $oldMessages = array_keys( FormatJson::decode( $oldBlob, true ) );
+ $newMessages = array_keys( FormatJson::decode( $newBlob, true ) );
+ $added = array_diff( $newMessages, $oldMessages );
+ $removed = array_diff( $oldMessages, $newMessages );
- // Delete removed messages, insert added ones
- if ( $removed ) {
- $dbw->delete( 'msg_resource_links', array(
- 'mrl_resource' => $name,
- 'mrl_message' => $removed
- ), __METHOD__
- );
- }
+ // Delete removed messages, insert added ones
+ if ( $removed ) {
+ $dbw->delete( 'msg_resource_links', array(
+ 'mrl_resource' => $name,
+ 'mrl_message' => $removed
+ ), __METHOD__
+ );
+ }
- $newLinksRows = array();
+ $newLinksRows = array();
- foreach ( $added as $message ) {
- $newLinksRows[] = array(
- 'mrl_resource' => $name,
- 'mrl_message' => $message
- );
- }
+ foreach ( $added as $message ) {
+ $newLinksRows[] = array(
+ 'mrl_resource' => $name,
+ 'mrl_message' => $message
+ );
+ }
- if ( $newLinksRows ) {
- $dbw->insert( 'msg_resource_links', $newLinksRows, __METHOD__,
- array( 'IGNORE' ) // just in case
- );
+ if ( $newLinksRows ) {
+ $dbw->insert( 'msg_resource_links', $newLinksRows, __METHOD__,
+ array( 'IGNORE' ) // just in case
+ );
+ }
+ } catch ( Exception $e ) {
+ wfDebug( __METHOD__ . " failed to update DB: $e\n" );
}
-
return $newBlob;
}
@@ -192,50 +198,58 @@ class MessageBlobStore {
* @param $key String: message key
*/
public static function updateMessage( $key ) {
- $dbw = wfGetDB( DB_MASTER );
-
- // Keep running until the updates queue is empty.
- // Due to update conflicts, the queue might not be emptied
- // in one iteration.
- $updates = null;
- do {
- $updates = self::getUpdatesForMessage( $key, $updates );
-
- foreach ( $updates as $k => $update ) {
- // Update the row on the condition that it
- // didn't change since we fetched it by putting
- // the timestamp in the WHERE clause.
- $success = $dbw->update( 'msg_resource',
- array(
- 'mr_blob' => $update['newBlob'],
- 'mr_timestamp' => $dbw->timestamp() ),
- array(
- 'mr_resource' => $update['resource'],
- 'mr_lang' => $update['lang'],
- 'mr_timestamp' => $update['timestamp'] ),
- __METHOD__
- );
+ try {
+ $dbw = wfGetDB( DB_MASTER );
+
+ // Keep running until the updates queue is empty.
+ // Due to update conflicts, the queue might not be emptied
+ // in one iteration.
+ $updates = null;
+ do {
+ $updates = self::getUpdatesForMessage( $key, $updates );
+
+ foreach ( $updates as $k => $update ) {
+ // Update the row on the condition that it
+ // didn't change since we fetched it by putting
+ // the timestamp in the WHERE clause.
+ $success = $dbw->update( 'msg_resource',
+ array(
+ 'mr_blob' => $update['newBlob'],
+ 'mr_timestamp' => $dbw->timestamp() ),
+ array(
+ 'mr_resource' => $update['resource'],
+ 'mr_lang' => $update['lang'],
+ 'mr_timestamp' => $update['timestamp'] ),
+ __METHOD__
+ );
- // Only requeue conflicted updates.
- // If update() returned false, don't retry, for
- // fear of getting into an infinite loop
- if ( !( $success && $dbw->affectedRows() == 0 ) ) {
- // Not conflicted
- unset( $updates[$k] );
+ // Only requeue conflicted updates.
+ // If update() returned false, don't retry, for
+ // fear of getting into an infinite loop
+ if ( !( $success && $dbw->affectedRows() == 0 ) ) {
+ // Not conflicted
+ unset( $updates[$k] );
+ }
}
- }
- } while ( count( $updates ) );
+ } while ( count( $updates ) );
- // No need to update msg_resource_links because we didn't add
- // or remove any messages, we just changed their contents.
+ // No need to update msg_resource_links because we didn't add
+ // or remove any messages, we just changed their contents.
+ } catch ( Exception $e ) {
+ wfDebug( __METHOD__ . " failed to update DB: $e\n" );
+ }
}
public static function clear() {
// TODO: Give this some more thought
// TODO: Is TRUNCATE better?
- $dbw = wfGetDB( DB_MASTER );
- $dbw->delete( 'msg_resource', '*', __METHOD__ );
- $dbw->delete( 'msg_resource_links', '*', __METHOD__ );
+ try {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->delete( 'msg_resource', '*', __METHOD__ );
+ $dbw->delete( 'msg_resource_links', '*', __METHOD__ );
+ } catch ( Exception $e ) {
+ wfDebug( __METHOD__ . " failed to update DB: $e\n" );
+ }
}
/**