Merge "[FileBackend] Added doQuickOperations() function for things like purging thumb...
[lhc/web/wiklou.git] / includes / filerepo / backend / FileBackendStore.php
index 5f49b01..1b788db 100644 (file)
@@ -257,6 +257,17 @@ abstract class FileBackendStore extends FileBackend {
                return $status;
        }
 
+       /**
+        * No-op file operation that does nothing.
+        * Do not call this function from places outside FileBackend and FileOp.
+        *
+        * @param $params Array
+        * @return Status
+        */
+       final public function nullInternal( array $params ) {
+               return Status::newGood();
+       }
+
        /**
         * @see FileBackend::concatenate()
         * @return Status
@@ -818,22 +829,6 @@ abstract class FileBackendStore extends FileBackend {
         */
        abstract public function getFileListInternal( $container, $dir, array $params );
 
-       /**
-        * Get the list of supported operations and their corresponding FileOp classes.
-        *
-        * @return Array
-        */
-       protected function supportedOperations() {
-               return array(
-                       'store'       => 'StoreFileOp',
-                       'copy'        => 'CopyFileOp',
-                       'move'        => 'MoveFileOp',
-                       'delete'      => 'DeleteFileOp',
-                       'create'      => 'CreateFileOp',
-                       'null'        => 'NullFileOp'
-               );
-       }
-
        /**
         * Return a list of FileOp objects from a list of operations.
         * Do not call this function from places outside FileBackend.
@@ -846,7 +841,14 @@ abstract class FileBackendStore extends FileBackend {
         * @throws MWException
         */
        final public function getOperationsInternal( array $ops ) {
-               $supportedOps = $this->supportedOperations();
+               $supportedOps = array(
+                       'store'       => 'StoreFileOp',
+                       'copy'        => 'CopyFileOp',
+                       'move'        => 'MoveFileOp',
+                       'delete'      => 'DeleteFileOp',
+                       'create'      => 'CreateFileOp',
+                       'null'        => 'NullFileOp'
+               );
 
                $performOps = array(); // array of FileOp objects
                // Build up ordered array of FileOps...
@@ -934,6 +936,59 @@ abstract class FileBackendStore extends FileBackend {
                return $status;
        }
 
+       /**
+        * @see FileBackend::doQuickOperationsInternal()
+        * @return Status
+        * @throws MWException
+        */
+       final protected function doQuickOperationsInternal( array $ops ) {
+               $status = Status::newGood();
+
+               $async = $this->parallelize;
+               $maxConcurrency = $this->concurrency; // throttle
+
+               $statuses = array(); // array of (index => Status)
+               $fileOpHandles = array(); // list of (index => handle) arrays
+               $curFileOpHandles = array(); // current handle batch
+               // Perform the sync-only ops and build up op handles for the async ops...
+               foreach ( $ops as $index => $params ) {
+                       $method = $params['op'] . 'Internal'; // e.g. "storeInternal"
+                       if ( !MWInit::methodExists( __CLASS__, $method ) ) {
+                               throw new MWException( "Operation '{$params['op']}' is not supported." );
+                       }
+                       $subStatus = $this->$method( array( 'async' => $async ) + $params );
+                       if ( $subStatus->value instanceof FileBackendStoreOpHandle ) { // async
+                               if ( count( $curFileOpHandles ) >= $maxConcurrency ) {
+                                       $fileOpHandles[] = $curFileOpHandles; // push this batch
+                                       $curFileOpHandles = array();
+                               }
+                               $curFileOpHandles[$index] = $subStatus->value; // keep index
+                       } else { // error or completed
+                               $statuses[$index] = $subStatus; // keep index
+                       }
+               }
+               if ( count( $curFileOpHandles ) ) {
+                       $fileOpHandles[] = $curFileOpHandles; // last batch
+               }
+               // Do all the async ops that can be done concurrently...
+               foreach ( $fileOpHandles as $fileHandleBatch ) {
+                       $statuses = $statuses + $this->executeOpHandlesInternal( $fileHandleBatch );
+               }
+               // Marshall and merge all the responses...
+               foreach ( $statuses as $index => $subStatus ) {
+                       $status->merge( $subStatus );
+                       if ( $subStatus->isOK() ) {
+                               $status->success[$index] = true;
+                               ++$status->successCount;
+                       } else {
+                               $status->success[$index] = false;
+                               ++$status->failCount;
+                       }
+               }
+
+               return $status;
+       }
+
        /**
         * Execute a list of FileBackendStoreOpHandle handles in parallel.
         * The resulting Status object fields will correspond
@@ -941,6 +996,7 @@ abstract class FileBackendStore extends FileBackend {
         *
         * @param $handles Array List of FileBackendStoreOpHandle objects
         * @return Array Map of Status objects
+        * @throws MWException
         */
        final public function executeOpHandlesInternal( array $fileOpHandles ) {
                wfProfileIn( __METHOD__ );
@@ -961,6 +1017,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * @see FileBackendStore::executeOpHandlesInternal()
         * @return Array List of corresponding Status objects
+        * @throws MWException
         */
        protected function doExecuteOpHandlesInternal( array $fileOpHandles ) {
                foreach ( $fileOpHandles as $fileOpHandle ) { // OK if empty
@@ -1263,7 +1320,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * Get the cache key for a container
         *
-        * @param $container Resolved container name
+        * @param $container string Resolved container name
         * @return string
         */
        private function containerCacheKey( $container ) {
@@ -1273,7 +1330,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * Set the cached info for a container
         *
-        * @param $container Resolved container name
+        * @param $container string Resolved container name
         * @param $val mixed Information to cache
         * @return void
         */
@@ -1284,7 +1341,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * Delete the cached info for a container
         *
-        * @param $container Resolved container name
+        * @param $containers string Resolved container name
         * @return void
         */
        final protected function deleteContainerCache( $container ) {
@@ -1352,7 +1409,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * Get the cache key for a file path
         *
-        * @param $path Storage path
+        * @param $path string Storage path
         * @return string
         */
        private function fileCacheKey( $path ) {
@@ -1362,7 +1419,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * Set the cached stat info for a file path
         *
-        * @param $path Storage path
+        * @param $path string Storage path
         * @param $val mixed Information to cache
         * @return void
         */
@@ -1373,7 +1430,7 @@ abstract class FileBackendStore extends FileBackend {
        /**
         * Delete the cached stat info for a file path
         *
-        * @param $path Storage path
+        * @param $path string Storage path
         * @return void
         */
        final protected function deleteFileCache( $path ) {