https://www.mediawiki.org/wiki/Special:Code/MediaWiki/106605

Revision: 106605
Author:   aaron
Date:     2011-12-18 21:50:41 +0000 (Sun, 18 Dec 2011)
Log Message:
-----------
* Added support for process caching and made it used for SHA-1. Non-FS backends 
will be more inclined to use this (PHP alreay caches FS stats).
* Refactored LockServerDaemon a bit to avoid "connect on construct" antipattern.

Modified Paths:
--------------
    branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php
    branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php
    
branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php
    branches/FileBackend/phase3/maintenance/locking/LockServerDaemon.php

Modified: 
branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php
===================================================================
--- branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php     
2011-12-18 21:43:31 UTC (rev 106604)
+++ branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php     
2011-12-18 21:50:41 UTC (rev 106605)
@@ -38,7 +38,7 @@
                return null;
        }
 
-       function store( array $params ) {
+       protected function doStore( array $params ) {
                $status = Status::newGood();
 
                list( $c, $dest ) = $this->resolveStoragePath( $params['dst'] );
@@ -79,7 +79,7 @@
                return $status;
        }
 
-       function copy( array $params ) {
+       protected function doCopy( array $params ) {
                $status = Status::newGood();
 
                list( $c, $source ) = $this->resolveStoragePath( $params['src'] 
);
@@ -127,7 +127,7 @@
                return $status;
        }
 
-       function move( array $params ) {
+       protected function doMove( array $params ) {
                $status = Status::newGood();
 
                list( $c, $source ) = $this->resolveStoragePath( $params['src'] 
);
@@ -176,7 +176,7 @@
                return $status;
        }
 
-       function delete( array $params ) {
+       protected function doDelete( array $params ) {
                $status = Status::newGood();
 
                list( $c, $source ) = $this->resolveStoragePath( $params['src'] 
);
@@ -203,7 +203,7 @@
                return $status;
        }
 
-       function concatenate( array $params ) {
+       protected function doConcatenate( array $params ) {
                $status = Status::newGood();
 
                list( $c, $dest ) = $this->resolveStoragePath( $params['dst'] );
@@ -301,7 +301,7 @@
                return $status;
        }
 
-       function create( array $params ) {
+       protected function doCreate( array $params ) {
                $status = Status::newGood();
 
                list( $c, $dest ) = $this->resolveStoragePath( $params['dst'] );

Modified: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php
===================================================================
--- branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php       
2011-12-18 21:43:31 UTC (rev 106604)
+++ branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php       
2011-12-18 21:50:41 UTC (rev 106605)
@@ -356,6 +356,10 @@
  * @since 1.19
  */
 abstract class FileBackend extends FileBackendBase {
+       /** @var Array */
+       protected $cache = array(); // (storage path => key => value)
+       protected $maxCacheSize = 50; // integer; max paths with entries
+
        /**
         * Store a file into the backend from a file on disk.
         * Do not call this function from places outside FileBackend and FileOp.
@@ -367,9 +371,18 @@
         * @param $params Array
         * @return Status
         */
-       abstract public function store( array $params );
+       final public function store( array $params ) {
+               $status = $this->doStore( $params );
+               $this->clearCache( array( $params['dst'] ) );
+               return $status;
+       }
 
        /**
+        * @see FileBackend::store()
+        */
+       abstract protected function doStore( array $params );
+
+       /**
         * Copy a file from one storage path to another in the backend.
         * Do not call this function from places outside FileBackend and FileOp.
         * $params include:
@@ -380,9 +393,18 @@
         * @param $params Array
         * @return Status
         */
-       abstract public function copy( array $params );
+       final public function copy( array $params ) {
+               $status = $this->doCopy( $params );
+               $this->clearCache( array( $params['dst'] ) );
+               return $status;
+       }
 
        /**
+        * @see FileBackend::copy()
+        */
+       abstract protected function doCopy( array $params );
+
+       /**
         * Delete a file at the storage path.
         * Do not call this function from places outside FileBackend and FileOp.
         * $params include:
@@ -391,9 +413,18 @@
         * @param $params Array
         * @return Status
         */
-       abstract public function delete( array $params );
+       final public function delete( array $params ) {
+               $status = $this->doDelete( $params );
+               $this->clearCache( array( $params['src'] ) );
+               return $status;
+       }
 
        /**
+        * @see FileBackend::delete()
+        */
+       abstract protected function doDelete( array $params );
+
+       /**
         * Move a file from one storage path to another in the backend.
         * Do not call this function from places outside FileBackend and FileOp.
         * $params include:
@@ -404,7 +435,16 @@
         * @param $params Array
         * @return Status
         */
-       public function move( array $params ) {
+       final public function move( array $params ) {
+               $status = $this->doMove( $params );
+               $this->clearCache( array( $params['src'], $params['dst'] ) );
+               return $status;
+       }
+
+       /**
+        * @see FileBackend::move()
+        */
+       protected function doMove( array $params ) {
                // Copy source to dest
                $status = $this->backend->copy( $params );
                if ( !$status->isOK() ) {
@@ -426,9 +466,18 @@
         * @param $params Array
         * @return Status
         */
-       abstract public function concatenate( array $params );
+       final public function concatenate( array $params ) {
+               $status = $this->doConcatenate( $params );
+               $this->clearCache( array( $params['dst'] ) );
+               return $status;
+       }
 
        /**
+        * @see FileBackend::concatenate()
+        */
+       abstract protected function doConcatenate( array $params );
+
+       /**
         * Create a file in the backend with the given contents.
         * Do not call this function from places outside FileBackend and FileOp.
         * $params include:
@@ -439,8 +488,17 @@
         * @param $params Array
         * @return Status
         */
-       abstract public function create( array $params );
+       final public function create( array $params ) {
+               $status = $this->doCreate( $params );
+               $this->clearCache( array( $params['dst'] ) );
+               return $status;
+       }
 
+       /**
+        * @see FileBackend::create()
+        */
+       abstract protected function doCreate( array $params );
+
        public function prepare( array $params ) {
                return Status::newGood();
        }
@@ -454,11 +512,20 @@
        }
 
        public function getFileSha1Base36( array $params ) {
-               $fsFile = $this->getLocalReference( array( 'src' => 
$params['src'] ) );
+               $path = $params['src'];
+               if ( isset( $this->cache[$path]['sha1'] ) ) {
+                       return $this->cache[$path]['sha1'];
+               }
+               $fsFile = $this->getLocalReference( array( 'src' => $path ) );
                if ( !$fsFile ) {
                        return false;
                } else {
-                       return $fsFile->getSha1Base36();
+                       $sha1 = $fsFile->getSha1Base36();
+                       if ( $sha1 !== false ) { // don't cache negatives
+                               $this->trimCache(); // limit memory
+                               $this->cache[$path]['sha1'] = $sha1;
+                       }
+                       return $sha1;
                }
        }
 
@@ -565,6 +632,8 @@
                        }
                }
 
+               // Clear any cache entries (after locks acquired)
+               $this->clearCache();
                // Actually attempt the operation batch...
                $status->merge( FileOp::attemptBatch( $performOps, $opts ) );
 
@@ -572,6 +641,35 @@
        }
 
        /**
+        * Invalidate the file existence and property cache
+        *
+        * @param $paths Array Clear cache for specific files
+        * @return void
+        */
+       final public function clearCache( array $paths = null ) {
+               if ( $paths === null ) {
+                       $this->cache = array();
+               } else {
+                       foreach ( $paths as $path ) {
+                               unset( $this->cache[$path] );
+                       }
+               }
+       }
+
+       /**
+        * Prune the cache if it is too big to add an item
+        * 
+        * @return void
+        */
+       protected function trimCache() {
+               if ( count( $this->cache ) >= $this->maxCacheSize ) {
+                       reset( $this->cache );
+                       $key = key( $this->cache );
+                       unset( $this->cache[$key] );
+               }
+       }
+
+       /**
         * Check if a given path is a mwstore:// path.
         * This does not do any actual validation or existence checks.
         * 

Modified: 
branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php
===================================================================
--- 
branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php 
    2011-12-18 21:43:31 UTC (rev 106604)
+++ 
branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php 
    2011-12-18 21:50:41 UTC (rev 106605)
@@ -93,6 +93,10 @@
                        return $status; // abort
                }
 
+               // Clear any cache entries (after locks acquired)
+               foreach ( $this->fileBackends as $backend ) {
+                       $backend->clearCache();
+               }
                // Actually attempt the operation batch...
                $status->merge( FileOp::attemptBatch( $performOps, $opts ) );
 
@@ -116,7 +120,7 @@
                                        $newOp[$par] = preg_replace(
                                                '!^mwstore://' . preg_quote( 
$this->name ) . '/!',
                                                'mwstore://' . 
$backend->getName() . '/',
-                                               $newOp[$par]
+                                               $newOp[$par] // string or array
                                        );
                                }
                        }

Modified: branches/FileBackend/phase3/maintenance/locking/LockServerDaemon.php
===================================================================
--- branches/FileBackend/phase3/maintenance/locking/LockServerDaemon.php        
2011-12-18 21:43:31 UTC (rev 106604)
+++ branches/FileBackend/phase3/maintenance/locking/LockServerDaemon.php        
2011-12-18 21:50:41 UTC (rev 106605)
@@ -35,11 +35,14 @@
        /** @var Array */
        protected $sessionIndexEx = array(); // (session => key => 1)
 
+       protected $address; // string (IP/hostname)
+       protected $port; // integer
        protected $authKey; // string key
        protected $connTimeout; // array ( 'sec' => integer, 'usec' => integer )
        protected $lockTimeout; // integer number of seconds
        protected $maxLocks; // integer
        protected $maxClients; // integer
+       protected $maxBacklog; // integer
 
        protected $startTime; // integer UNIX timestamp
        protected $lockCount = 0; // integer
@@ -70,7 +73,10 @@
                        } 
                }
 
+               $this->address = $config['address'];
+               $this->port = $config['port'];
                $this->authKey = $config['authKey'];
+
                $connTimeout = isset( $config['connTimeout'] )
                        ? $config['connTimeout']
                        : 1.5;
@@ -87,10 +93,15 @@
                $this->maxClients = isset( $config['maxClients'] )
                        ? $config['maxClients']
                        : 100;
-               $backlog = isset( $config['maxBacklog'] )
+               $this->maxBacklog = isset( $config['maxBacklog'] )
                        ? $config['maxBacklog']
                        : 10;
+       }
 
+       /**
+        * @return void
+        */
+       protected function setupSocket() {
                if ( !function_exists( 'socket_create' ) ) {
                        throw new Exception( "PHP sockets extension missing 
from PHP CLI mode." );
                }
@@ -99,10 +110,10 @@
                        throw new Exception( "socket_create(): " . 
socket_strerror( socket_last_error() ) );
                }
                socket_set_option( $sock, SOL_SOCKET, SO_REUSEADDR, 1 ); // 
bypass 2MLS
-               if ( socket_bind( $sock, $config['address'], $config['port'] ) 
=== false ) {
+               if ( socket_bind( $sock, $this->address, $this->port ) === 
false ) {
                        throw new Exception( "socket_bind(): " .
                                socket_strerror( socket_last_error( $sock ) ) );
-               } elseif ( socket_listen( $sock, $backlog ) === false ) {
+               } elseif ( socket_listen( $sock, $this->maxBacklog ) === false 
) {
                        throw new Exception( "socket_listen(): " .
                                socket_strerror( socket_last_error( $sock ) ) );
                }
@@ -115,6 +126,8 @@
         * @return void
         */
        public function main() {
+               // Setup socket and start listing
+               $this->setupSocket();
                // Create a list of all the clients that will be connected to 
us.
                $clients = array( $this->sock ); // start off with listening 
socket
                do {


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to