Index: trunk/phase3/includes/ExternalStore.php |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | */ |
16 | 16 | class ExternalStore { |
17 | 17 | /* Fetch data from given URL */ |
18 | | - static function fetchFromURL($url) { |
| 18 | + static function fetchFromURL( $url ) { |
19 | 19 | global $wgExternalStores; |
20 | 20 | |
21 | 21 | if( !$wgExternalStores ) |
— | — | @@ -44,7 +44,7 @@ |
45 | 45 | |
46 | 46 | $class = 'ExternalStore' . ucfirst( $proto ); |
47 | 47 | /* Any custom modules should be added to $wgAutoLoadClasses for on-demand loading */ |
48 | | - if( !class_exists( $class ) ){ |
| 48 | + if( !class_exists( $class ) ) { |
49 | 49 | return false; |
50 | 50 | } |
51 | 51 | |
— | — | @@ -66,4 +66,47 @@ |
67 | 67 | return $store->store( $params, $data ); |
68 | 68 | } |
69 | 69 | } |
| 70 | + |
| 71 | + /** |
| 72 | + * Like insert() above, but does more of the work for us. |
| 73 | + * This function does not need a url param, it builds it by |
| 74 | + * itself. It also fails-over to the next possible clusters. |
| 75 | + * |
| 76 | + * @param string $data |
| 77 | + * Returns the URL of the stored data item, or false on error |
| 78 | + */ |
| 79 | + public static function randomInsert( $data ) { |
| 80 | + global $wgDefaultExternalStore; |
| 81 | + $tryStores = (array)$wgDefaultExternalStore; |
| 82 | + $error = false; |
| 83 | + while ( count( $tryStores ) > 0 ) { |
| 84 | + $index = mt_rand(0, count( $tryStores ) - 1); |
| 85 | + $storeUrl = $tryStores[$index]; |
| 86 | + wfDebug( __METHOD__.": trying $storeUrl\n" ); |
| 87 | + list( $proto, $params ) = explode( '://', $storeUrl, 2 ); |
| 88 | + $store = self::getStoreObject( $proto ); |
| 89 | + if ( $store === false ) { |
| 90 | + throw new MWException( "Invalid external storage protocol - $storeUrl" ); |
| 91 | + } |
| 92 | + try { |
| 93 | + $url = $store->store( $params, $data ); // Try to save the object |
| 94 | + } catch ( DBConnectionError $error ) { |
| 95 | + $url = false; |
| 96 | + } |
| 97 | + if ( $url ) { |
| 98 | + return $url; // Done! |
| 99 | + } else { |
| 100 | + unset( $tryStores[$index] ); // Don't try this one again! |
| 101 | + $tryStores = array_values( $tryStores ); // Must have consecutive keys |
| 102 | + wfDebugLog( 'ExternalStorage', "Unable to store text to external storage $storeUrl" ); |
| 103 | + } |
| 104 | + } |
| 105 | + // All stores failed |
| 106 | + if ( $error ) { |
| 107 | + // Rethrow the last connection error |
| 108 | + throw $error; |
| 109 | + } else { |
| 110 | + throw new MWException( "Unable to store text to external storage" ); |
| 111 | + } |
| 112 | + } |
70 | 113 | } |
Index: trunk/phase3/includes/ExternalStoreDB.php |
— | — | @@ -56,7 +56,7 @@ |
57 | 57 | * Fetch data from given URL |
58 | 58 | * @param string $url An url of the form DB://cluster/id or DB://cluster/id/itemid for concatened storage. |
59 | 59 | */ |
60 | | - function fetchFromURL($url) { |
| 60 | + function fetchFromURL( $url ) { |
61 | 61 | $path = explode( '/', $url ); |
62 | 62 | $cluster = $path[2]; |
63 | 63 | $id = $path[3]; |
— | — | @@ -122,12 +122,14 @@ |
123 | 123 | * @return string URL |
124 | 124 | */ |
125 | 125 | function store( $cluster, $data ) { |
126 | | - $fname = 'ExternalStoreDB::store'; |
127 | | - |
128 | | - $dbw =& $this->getMaster( $cluster ); |
129 | | - |
| 126 | + $dbw = $this->getMaster( $cluster ); |
| 127 | + if( !$dbw ) { |
| 128 | + return false; |
| 129 | + } |
130 | 130 | $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' ); |
131 | | - $dbw->insert( $this->getTable( $dbw ), array( 'blob_id' => $id, 'blob_text' => $data ), $fname ); |
| 131 | + $dbw->insert( $this->getTable( $dbw ), |
| 132 | + array( 'blob_id' => $id, 'blob_text' => $data ), |
| 133 | + __METHOD__ ); |
132 | 134 | $id = $dbw->insertId(); |
133 | 135 | if ( $dbw->getFlag( DBO_TRX ) ) { |
134 | 136 | $dbw->immediateCommit(); |