Seb35 has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/299398

Change subject: Generalisation of cache files to all files read.
......................................................................

Generalisation of cache files to all files read.

For now it is in the subdirectory '.cache' of the config directory.
Composer is now only loaded when YAML files must be read.

Performance has drastically improved (in ms):

    mean   = 4.7572
    median = 4.3525
    std    = 0.9047
    min    = 3.8898
    max    = 6.9201
    range  = 3.0303
    samples = 50

Performance in the case nothing is cached is about 12ms; it is between
if some files are cached. For information, an equivalent LocalSettings.php
is loaded in 2.9ms (mean). So this extension takes ~1.85ms.

Possibly performance could be still improved by creating a unique file with
all existing wikis (of a farm) with their version associated, although there
is no certainty about that (possibly a big file could take more time than
two small files).
---
M src/MediaWikiFarm.php
1 file changed, 56 insertions(+), 53 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MediaWikiFarm 
refs/changes/98/299398/1

diff --git a/src/MediaWikiFarm.php b/src/MediaWikiFarm.php
index a5c74d5..69e94cb 100644
--- a/src/MediaWikiFarm.php
+++ b/src/MediaWikiFarm.php
@@ -10,10 +10,6 @@
 # Protect against web entry
 if( !defined( 'MEDIAWIKI' ) && !defined( 'MEDIAWIKI_FARM' ) ) exit;
 
-# Load Composer libraries
-# There is no warning if not present because the only library loaded (YAML) 
could not be useful in some installations.
-@include_once __DIR__ . '/../vendor/autoload.php';
-
 /**
  * This class computes the configuration of a specific wiki from a set of 
configuration files.
  * The configuration is composed of the list of authorised wikis and different 
configuration
@@ -264,9 +260,9 @@
                $this->codeDir = $codeDir;
                
                # Read the farm(s) configuration
-               if( $configs = $this->readFile( $this->configDir . '/farms.yml' 
) );
-               elseif( $configs = $this->readFile( $this->configDir . 
'/farms.php' ) );
-               elseif( $configs = $this->readFile( $this->configDir . 
'/farms.json' ) );
+               if( $configs = $this->readFile( 'farms.yml', $this->configDir ) 
);
+               elseif( $configs = $this->readFile( '/farms.json', 
$this->configDir ) );
+               elseif( $configs = $this->readFile( '/farms.php', 
$this->configDir ) );
                else $this->unusable = true;
                
                # Now select the right configuration amoung all farms
@@ -351,7 +347,7 @@
                                continue;
                        
                        # Really check if the variable is in the listing file
-                       $choices = $this->readFile( $this->configDir . '/' . 
$this->replaceVariables( $variable['file'] ) );
+                       $choices = $this->readFile( $this->replaceVariables( 
$variable['file'] ), $this->configDir );
                        if( $choices === false ) {
                                $this->unusable = true;
                                return false;
@@ -390,11 +386,11 @@
                
                # Set suffix
                $this->setWikiProperty( 'suffix' );
-               $this->variables['suffix'] = $this->params['suffix'];
+               $this->variables['SUFFIX'] = $this->params['suffix'];
                
                # Set wikiID
                $this->setWikiProperty( 'wikiID' );
-               $this->variables['wikiID'] = $this->params['wikiID'];
+               $this->variables['WIKI'] = $this->params['wikiID'];
                
                # Check consistency
                if( !$this->params['suffix'] || !$this->params['wikiID'] ) {
@@ -426,7 +422,7 @@
                # In the case multiversion is configured, but version is not 
known as of now
                elseif( is_string( $this->codeDir ) && is_null( $version ) ) {
                        
-                       $versions = $this->readFile( $this->params['versions'] 
);
+                       $versions = $this->readFile( $this->params['versions'], 
$this->configDir );
                        
                        if( !$versions ) {
                                $this->unusable = true;
@@ -459,7 +455,7 @@
                }
                
                # Set the version in the wiki configuration and as a variable 
to be used later
-               $this->variables['version'] = $version;
+               $this->variables['VERSION'] = $version;
                $this->params['version'] = $version;
                
                return true;
@@ -476,7 +472,6 @@
                        $this->params['config'] = array();
                
                $this->setWikiProperty( 'data' );
-               $this->setWikiProperty( 'cache' );
                $this->setWikiProperty( 'config' );
                
                return true;
@@ -488,16 +483,16 @@
         * @todo Still hacky: before setting parameters in stone in farms.yml, 
various configurations should be reviewed to select accordingly the rights 
management modelisation
         * @return void
         */
-       private function setWgConf() {
+       /*private function setWgConf() {
                
                global $wgConf;
                
                $wgConf->suffixes = array( $this->params['suffix'] );
-               $wikiIDs = $this->readFile( $this->configDir . '/' . 
$this->params['suffix'] . '/wikis.yml' );
+               $wikiIDs = $this->readFile( $this->params['suffix'] . 
'/wikis.yml', $this->configDir );
                foreach( array_keys( $wikiIDs ) as $wiki ) {
                        $wgConf->wikis[] = $wiki . '-' . 
$this->params['suffix'];
                }
-       }
+       }*/
        
        /**
         * Get or compute the configuration (MediaWiki, skins, extensions) for 
a wiki.
@@ -529,7 +524,7 @@
                $myWiki = $this->params['wikiID'];
                $mySuffix = $this->params['suffix'];
                
-               $cacheFile = $this->params['cache'];
+               $cacheFile = $this->replaceVariables( 
'$VERSION-$SUFFIX-$WIKI.ser' );
                
                //var_dump($wgConf);
                //var_dump($cacheFile);
@@ -543,8 +538,8 @@
                
                $this->params['globals'] = false;
                
-               if( $cacheFile && is_string( $cacheFile ) && is_file( 
$cacheFile) && @filemtime( $cacheFile ) >= $oldness )
-                       $this->params['globals'] = $this->readFile( $cacheFile 
);
+               if( array_key_exists( 'cache', $this->params ) && is_file( 
$this->configDir . '/.cache/' . $cacheFile ) && @filemtime( $this->configDir . 
'/.cache/' . $cacheFile ) >= $oldness )
+                       $this->params['globals'] = $this->readFile( $cacheFile, 
$this->configDir . '/.cache' );
                
                else {
                        
@@ -580,8 +575,7 @@
                        $globals['extensions']['MediaWikiFarm'] = array( 
'_loading' => 'wfLoadExtension' );
                        
                        # Save this configuration in a serialised file
-                       if( $cacheFile )
-                               $this->cacheFile( $globals, $cacheFile );
+                       $this->cacheFile( $globals, $cacheFile );
                }
        }
        
@@ -604,7 +598,7 @@
                        # Executable config files
                        if( array_key_exists( 'exec', $configFile ) ) continue;
                        
-                       $theseSettings = $this->readFile( $this->configDir . 
'/' . $configFile['file'] );
+                       $theseSettings = $this->readFile( $configFile['file'], 
$this->configDir );
                        if( $theseSettings === false ) {
                                $this->unusable = true;
                                return false;
@@ -781,19 +775,19 @@
                $format = preg_replace( '/^.*\.([a-z]+)$/', '$1', $filename );
                
                # Check the file exists
-               $filename = $directory ? $directory . '/' . $filename : 
$filename;
-               if( !is_file( $filename ) )
+               $prefixedFile = $directory ? $directory . '/' . $filename : 
$filename;
+               if( !is_file( $prefixedFile ) )
                        return false;
                
                # Format PHP
                if( $format == 'php' )
                        
-                       $array = @include $filename;
+                       $array = @include $prefixedFile;
                
                # Format 'serialisation'
                elseif( $format == 'ser' ) {
                        
-                       $content = @file_get_contents( $filename );
+                       $content = @file_get_contents( $prefixedFile );
                        
                        if( !$content )
                                return array();
@@ -801,14 +795,24 @@
                        $array = @unserialize( $content );
                }
                
+               # Cached version
+               elseif( is_file( $this->configDir . '/.cache/' . $filename . 
'.ser' ) && @filemtime( $this->configDir . '/.cache/' . $filename . '.ser' ) >= 
@filemtime( $prefixedFile ) )
+                       
+                       return $this->readFile( $filename . '.ser', 
$this->configDir . '/.cache' );
+               
                # Format YAML
                elseif( $format == 'yml' || $format == 'yaml' ) {
                        
-                       if( !class_exists( 'Symfony\Component\Yaml\Yaml' ) )
+                       # Load Composer libraries
+                       # There is no warning if not present because to 
properly handle the error by returning false
+                       # This is only included here to avoid delays (~3ms) 
during the loading using cached files or other formats
+                       @include_once __DIR__ . '/../vendor/autoload.php';
+                       
+                       if( !class_exists( 'Symfony\Component\Yaml\Yaml' ) || 
!class_exists( 'Symfony\Component\Yaml\Exception\ParseException' ) )
                                return false;
                        
                        try {
-                               $array = Symfony\Component\Yaml\Yaml::parse( 
@file_get_contents( $filename ) );
+                               $array = Symfony\Component\Yaml\Yaml::parse( 
@file_get_contents( $prefixedFile ) );
                        }
                        catch( Symfony\Component\Yaml\Exception\ParseException 
$e ) {
                                
@@ -819,12 +823,12 @@
                # Format JSON
                elseif( $format == 'json' )
                        
-                       $array = json_decode( @file_get_contents( $filename ), 
true );
+                       $array = json_decode( @file_get_contents( $prefixedFile 
), true );
                
                # Format 'dblist' (simple list of strings separated by newlines)
                elseif( $format == 'dblist' ) {
                        
-                       $content = @file_get_contents( $filename );
+                       $content = @file_get_contents( $prefixedFile );
                        
                        if( !$content )
                                return array();
@@ -835,13 +839,18 @@
                # Error for any other format
                else return false;
                
-               # Regular return for arrays
-               if( is_array( $array ) )
-                       return $array;
+               # A null value is an empty file or value 'null'
+               if( is_null( $array ) )
+                       $array = array();
                
-               # Return an empty array if null (empty file or value 'null)
-               elseif( is_null( $array ) )
-                       return array();
+               # Regular return for arrays
+               if( is_array( $array ) ) {
+                       
+                       if( $format !== 'php' && $format !== 'ser' )
+                               $this->cacheFile( $array, $filename.'.ser' );
+                       
+                       return $array;
+               }
                
                # Error for any other type
                return false;
@@ -851,32 +860,26 @@
         * Create a cache file.
         * 
         * @param array $array Array of the data to be cached.
-        * @param string $filename Name of the cache file.
-        * @param string $format Format of the cache file, in ['ser', 'php'].
+        * @param string $filename Name of the cache file; this filename must 
have an extension '.ser' or '.php' else no cache file is saved.
         * @return void
         */
-       private function cacheFile( $array, $filename, $format = 'ser' ) {
+       private function cacheFile( $array, $filename ) {
                
-               if( !array_key_exists( 'cache', $this->params ) )
-                       return;
+               $prefixedFile = $this->configDir . '/.cache/' . $filename;
                
                # Create temporary file
-               @mkdir( dirname( $filename ) );
-               $tmpFile = tempnam( dirname( $filename ), $filename.'.tmp' );
-               chmod( $tmpFile, 0644 );
+               @mkdir( dirname( $prefixedFile ) );
+               $tmpFile = $prefixedFile . '.tmp';
                
-               if( !$tmpFile )
-                       return;
-               
-               if( $format == 'php' ) {
-                       if( file_put_contents( $tmpFile, "<?php\n\n// WARNING: 
file automatically generated: do not modify.\n\nreturn ".var_export( $array, 
true ).';' ) )
-                               rename( $tmpFile, $filename );
-               }
-               elseif( $format == 'ser' ) {
+               if( preg_match( '/\.ser$/', $filename ) ) {
                        if( file_put_contents( $tmpFile, serialize( $array ) ) 
) {
-                               rename( $tmpFile, $filename );
+                               rename( $tmpFile, $prefixedFile );
                        }
                }
+               elseif( preg_match( '/\.php$/', $filename ) ) {
+                       if( file_put_contents( $tmpFile, "<?php\n\n// WARNING: 
file automatically generated: do not modify.\n\nreturn ".var_export( $array, 
true ).';' ) )
+                               rename( $tmpFile, $prefixedFile );
+               }
        }
        
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/299398
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ide9a65229f7dfe2db8ae103a7ffa974663be1295
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MediaWikiFarm
Gerrit-Branch: master
Gerrit-Owner: Seb35 <seb35wikipe...@gmail.com>

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

Reply via email to