From: Aaron Schulz Date: Thu, 22 Feb 2018 08:27:14 +0000 (-0800) Subject: Add ExternalStoreMedium::isReadOnly() method X-Git-Tag: 1.31.0-rc.0~531^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=656f60c15434afb69d60e511cfebf84fc4fbc2c2 Add ExternalStoreMedium::isReadOnly() method Use this to abort out of store() calls early Bug: T187942 Change-Id: I9334d36e8bc3e4589775471eee03be4f4a3119a3 --- diff --git a/includes/externalstore/ExternalStore.php b/includes/externalstore/ExternalStore.php index 3beab29532..2ac6f7e82f 100644 --- a/includes/externalstore/ExternalStore.php +++ b/includes/externalstore/ExternalStore.php @@ -92,6 +92,7 @@ class ExternalStore { * @param array $urls The URLs of the text to get * @return array Map from url to its data. Data is either string when found * or false on failure. + * @throws MWException */ public static function batchFetchFromURLs( array $urls ) { $batches = []; @@ -190,19 +191,25 @@ class ExternalStore { if ( $store === false ) { throw new MWException( "Invalid external storage protocol - $storeUrl" ); } + try { - $url = $store->store( $path, $data ); // Try to save the object + if ( $store->isReadOnly( $path ) ) { + $msg = 'read only'; + } else { + $url = $store->store( $path, $data ); + if ( strlen( $url ) ) { + return $url; // a store accepted the write; done! + } + $msg = 'operation failed'; + } } catch ( Exception $error ) { - $url = false; - } - if ( strlen( $url ) ) { - return $url; // Done! - } else { - unset( $tryStores[$index] ); // Don't try this one again! - $tryStores = array_values( $tryStores ); // Must have consecutive keys - wfDebugLog( 'ExternalStorage', - "Unable to store text to external storage $storeUrl" ); + $msg = 'caught exception'; } + + unset( $tryStores[$index] ); // Don't try this one again! + $tryStores = array_values( $tryStores ); // Must have consecutive keys + wfDebugLog( 'ExternalStorage', + "Unable to store text to external storage $storeUrl ($msg)" ); } // All stores failed if ( $error ) { diff --git a/includes/externalstore/ExternalStoreDB.php b/includes/externalstore/ExternalStoreDB.php index e5d36e10cb..b43bd210aa 100644 --- a/includes/externalstore/ExternalStoreDB.php +++ b/includes/externalstore/ExternalStoreDB.php @@ -103,6 +103,10 @@ class ExternalStoreDB extends ExternalStoreMedium { return "DB://$location/$id"; } + public function isReadOnly( $location ) { + return ( $this->getLoadBalancer( $location )->getReadOnlyReason() !== false ); + } + /** * Get a LoadBalancer for the specified cluster * diff --git a/includes/externalstore/ExternalStoreHttp.php b/includes/externalstore/ExternalStoreHttp.php index 8e1e49fa60..3d812c96ae 100644 --- a/includes/externalstore/ExternalStoreHttp.php +++ b/includes/externalstore/ExternalStoreHttp.php @@ -27,24 +27,15 @@ * @ingroup ExternalStorage */ class ExternalStoreHttp extends ExternalStoreMedium { - /** - * @see ExternalStoreMedium::fetchFromURL() - * @param string $url - * @return string|bool - * @throws MWException - */ public function fetchFromURL( $url ) { return Http::get( $url, [], __METHOD__ ); } - /** - * @see ExternalStoreMedium::store() - * @param string $cluster - * @param string $data - * @return string|bool - * @throws MWException - */ - public function store( $cluster, $data ) { + public function store( $location, $data ) { throw new MWException( "ExternalStoreHttp is read-only and does not support store()." ); } + + public function isReadOnly( $location ) { + return true; + } } diff --git a/includes/externalstore/ExternalStoreMedium.php b/includes/externalstore/ExternalStoreMedium.php index 6cfa08389e..f1eaa93b9f 100644 --- a/includes/externalstore/ExternalStoreMedium.php +++ b/includes/externalstore/ExternalStoreMedium.php @@ -76,4 +76,15 @@ abstract class ExternalStoreMedium { * @throws MWException */ abstract public function store( $location, $data ); + + /** + * Check if a given location is read-only + * + * @param string $location The location name + * @return bool Whether this location is read-only + * @since 1.31 + */ + public function isReadOnly( $location ) { + return false; + } } diff --git a/includes/externalstore/ExternalStoreMwstore.php b/includes/externalstore/ExternalStoreMwstore.php index 5395f56274..0c6d022fc5 100644 --- a/includes/externalstore/ExternalStoreMwstore.php +++ b/includes/externalstore/ExternalStoreMwstore.php @@ -73,13 +73,6 @@ class ExternalStoreMwstore extends ExternalStoreMedium { return $blobs; } - /** - * @see ExternalStoreMedium::store() - * @param string $backend - * @param string $data - * @return string|bool - * @throws MWException - */ public function store( $backend, $data ) { $be = FileBackendGroup::singleton()->get( $backend ); if ( $be instanceof FileBackend ) { @@ -103,4 +96,10 @@ class ExternalStoreMwstore extends ExternalStoreMedium { return false; } + + public function isReadOnly( $backend ) { + $be = FileBackendGroup::singleton()->get( $backend ); + + return $be ? $be->isReadOnly() : false; + } }