http://www.mediawiki.org/wiki/Special:Code/MediaWiki/99341

Revision: 99341
Author:   kaldari
Date:     2011-10-09 08:33:44 +0000 (Sun, 09 Oct 2011)
Log Message:
-----------
entirely new scheme to optimize banner loading - down from 1.1 seconds to 0.1 
seconds - needs more testing

Modified Paths:
--------------
    trunk/extensions/CentralNotice/CentralNotice.php
    trunk/extensions/CentralNotice/special/SpecialBannerController.php
    trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php

Modified: trunk/extensions/CentralNotice/CentralNotice.php
===================================================================
--- trunk/extensions/CentralNotice/CentralNotice.php    2011-10-09 06:56:49 UTC 
(rev 99340)
+++ trunk/extensions/CentralNotice/CentralNotice.php    2011-10-09 08:33:44 UTC 
(rev 99341)
@@ -102,9 +102,8 @@
 
        if ( $wgCentralNoticeLoader ) {
                $wgHooks['LoadExtensionSchemaUpdates'][] = 
'efCentralNoticeSchema';
-               $wgHooks['BeforePageDisplay'][] = 'efCentralNoticeLoader';
                $wgHooks['MakeGlobalVariablesScript'][] = 
'efCentralNoticeDefaults';
-               $wgHooks['SiteNoticeAfter'][] = 'efCentralNoticeDisplay';
+               $wgHooks['SiteNoticeAfter'][] = 'efCentralNoticeLoader';
                $wgHooks['SkinAfterBottomScripts'][] = 
'efCentralNoticeGeoLoader';
        }
 
@@ -200,40 +199,38 @@
        return true;
 }
 
-function efCentralNoticeLoader( $out, $skin ) {
-       global $wgOut;
-
-       // Include '.js' to exempt script from squid cache expiration override
-       $centralLoader = SpecialPage::getTitleFor( 'BannerController' 
)->getLocalUrl( 'cache=/cn.js' );
-
-       // Insert the banner controller Javascript into the <head>
-       $wgOut->addScriptFile( $centralLoader );
-
-       return true;
-}
-
 function efCentralNoticeGeoLoader( $skin, &$text ) {
-       // Insert the geo IP lookup
-       $text .= '<script type="text/javascript" 
src="//geoiplookup.wikimedia.org/"></script>';
+       // Insert the geo IP lookup and cookie setter
+       $text .= <<<HTML
+<script type="text/javascript" src="//geoiplookup.wikimedia.org/"></script>
+<script>
+var e = new Date();
+e.setTime( e.getTime() + (30*24*60*60*1000) ); // 30 days
+document.cookie = 'geo_country=' + Geo.country + '; expires=' + 
e.toGMTString() + '; path=/';
+</script>
+HTML;
        return true;
 }
 
 function efCentralNoticeDefaults( &$vars ) {
        global $wgNoticeProject;
-       // Initialize global Javascript variables. We initialize Geo with empty 
values so if the geo
-       // IP lookup fails we don't have any surprises.
+       // Initialize global Javascript variables
        $geo = (object)array();
        $geo->{'city'} = '';
-       $geo->{'country'} = '';
-       $vars['Geo'] = $geo; // change this to wgGeo as soon as Mark updates on 
his end
+       if ( array_key_exists( 'geo_country', $_COOKIE ) && 
$_COOKIE['geo_country'] != '' ) {
+               $geo->{'country'} = $_COOKIE['geo_country'];
+       } else {
+               $geo->{'country'} = '';
+       }
+       $vars['Geo'] = $geo;
        $vars['wgNoticeProject'] = $wgNoticeProject;
        return true;
 }
 
-function efCentralNoticeDisplay( &$notice ) {
+function efCentralNoticeLoader( &$notice ) {
        // setup siteNotice div
-       $notice =
-               '<!-- centralNotice loads here -->'. // hack for IE8 to 
collapse empty div
-               $notice;
+       // Include '.js' to exempt script from squid cache expiration override
+       $centralLoader = SpecialPage::getTitleFor( 'BannerController' 
)->getLocalUrl( 'cache=/cn.js' );
+       $notice .= '<!-- centralNotice loads here --><script 
type="text/javascript" src="'.$centralLoader.'"></script>';
        return true;
 }

Modified: trunk/extensions/CentralNotice/special/SpecialBannerController.php
===================================================================
--- trunk/extensions/CentralNotice/special/SpecialBannerController.php  
2011-10-09 06:56:49 UTC (rev 99340)
+++ trunk/extensions/CentralNotice/special/SpecialBannerController.php  
2011-10-09 08:33:44 UTC (rev 99341)
@@ -4,8 +4,8 @@
  * Generates Javascript file which controls banner selection on the client side
  */
 class SpecialBannerController extends UnlistedSpecialPage {
-       protected $sharedMaxAge = 3600; // Cache for 1 hour on the server side
-       protected $maxAge = 3600; // Cache for 1 hour on the client side
+       protected $sharedMaxAge = 300; // Cache for 5 minutes on the server side
+       protected $maxAge = 300; // Cache for 5 minutes on the client side
 
        function __construct() {
                // Register special page
@@ -19,16 +19,11 @@
                $this->sendHeaders();
                
                $content = $this->getOutput();
-               if ( strlen( $content ) == 0 ) {
-                       // Hack for IE/Mac 0-length keepalive problem, see 
RawPage.php
-                       echo "/* Empty */";
-               } else {
-                       echo $content;
-               }
+               echo $content;
        }
        
        /**
-        * Generate the HTTP response headers for the banner controller
+        * Generate the HTTP response headers
         */
        function sendHeaders() {
                global $wgJsMimeType;
@@ -45,7 +40,7 @@
        function getOutput() {
                global $wgCentralPagePath, $wgContLang;
                
-               $js = $this->getScriptFunctions() . $this->getToggleScripts();
+               $js = $this->getAllBannerLists() . $this->getScriptFunctions() 
. $this->getToggleScripts();
                $js .= <<<JAVASCRIPT
 ( function( $ ) {
        $.ajaxSetup({ cache: true });
@@ -81,22 +76,12 @@
                                } else {
                                        var geoLocation = Geo.country; // pull 
the geo info
                                }
-                               var bannerListQuery = $.param( { 'language': 
wgContentLanguage, 'project': wgNoticeProject, 'country': geoLocation } );
-JAVASCRIPT;
-               $js .= "\n\t\t\t\tvar bannerListURL = wgScript + '?title=' + 
encodeURIComponent('" . 
-                       $wgContLang->specialPage( 'BannerListLoader' ) .
-                       "') + '&cache=/cn.js&' + bannerListQuery;\n";
-               $js .= <<<JAVASCRIPT
-                               var request = $.ajax( {
-                                       url: bannerListURL,
-                                       dataType: 'json',
-                                       success: $.centralNotice.fn.chooseBanner
-                               } );
+                               var bannerList = $.parseJSON( 
wgBannerList[geoLocation] );
+                               $.centralNotice.fn.chooseBanner( bannerList );
                        },
                        'chooseBanner': function( bannerList ) {
                                // Convert the json object to a true array
                                bannerList = Array.prototype.slice.call( 
bannerList );
-                               
                                // Make sure there are some banners to choose 
from
                                if ( bannerList.length == 0 ) return false;
                                
@@ -137,17 +122,29 @@
                        }
                }
        }
-       $( document ).ready( function () {
-               // Initialize the query string vars
-               $.centralNotice.fn.getQueryStringVariables();
+       // Initialize the query string vars
+       $.centralNotice.fn.getQueryStringVariables();
+       if ( Geo.country ) {
+               // We know the user's country so go ahead and load everything
                if( $.centralNotice.data.getVars['banner'] ) {
-                       // if we're forcing one banner
+                       // We're forcing one banner
                        $.centralNotice.fn.loadBanner( 
$.centralNotice.data.getVars['banner'] );
                } else {
                        // Look for banners ready to go NOW
                        $.centralNotice.fn.loadBannerList( 
$.centralNotice.data.getVars['country'] );
                }
-       } ); //document ready
+       } else {
+               // We don't know the user's country yet, so we have to wait for 
the GeoIP lookup
+               $( document ).ready( function () {
+                       if( $.centralNotice.data.getVars['banner'] ) {
+                               // We're forcing one banner
+                               $.centralNotice.fn.loadBanner( 
$.centralNotice.data.getVars['banner'] );
+                       } else {
+                               // Look for banners ready to go NOW
+                               $.centralNotice.fn.loadBannerList( 
$.centralNotice.data.getVars['country'] );
+                       }
+               } ); //document ready
+       }
 } )( jQuery );
 JAVASCRIPT;
                return $js;
@@ -218,5 +215,41 @@
 JAVASCRIPT;
                return $script;
        }
+       
+       /**
+        * Generate all the banner lists for all the countries
+        */
+       function getAllBannerLists() {
+               $script = "var wgBannerList = new Array();\r\n";
+               $countriesList = CentralNoticeDB::getCountriesList();
+               foreach ( $countriesList as $countryCode => $countryName ) {
+                       $script .= "wgBannerList['$countryCode'] = 
'".$this->getBannerList( $countryCode )."';\r\n";
+               }
+               return $script;
+       }
+       
+       /**
+        * Generate JSON banner list for a given country
+        */
+       function getBannerList( $country ) {
+               global $wgNoticeProject, $wgNoticeLang;
+               $banners = array();
+               
+               // See if we have any preferred campaigns for this language and 
project
+               $campaigns = CentralNoticeDB::getCampaigns( $wgNoticeProject, 
$wgNoticeLang, null, 1, 1, $country );
+               
+               // Quick short circuit to show preferred campaigns
+               if ( $campaigns ) {
+                       // Pull banners
+                       $banners = CentralNoticeDB::getCampaignBanners( 
$campaigns );
+               }
 
+               // Didn't find any preferred banners so do an old style lookup
+               if ( !$banners )  {
+                       $banners = CentralNoticeDB::getBannersByTarget( 
$wgNoticeProject, $wgNoticeLang, $country );
+               }
+               
+               return FormatJson::encode( $banners );
+       }
+
 }

Modified: trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php
===================================================================
--- trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php  
2011-10-09 06:56:49 UTC (rev 99340)
+++ trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php  
2011-10-09 08:33:44 UTC (rev 99341)
@@ -1,6 +1,7 @@
 <?php
 
 /**
+ * Note: This file is deprecated and should be deleted if the new banner 
loading system works better.
  * Generates JSON files listing all the banners for a particular site
  */
 class SpecialBannerListLoader extends UnlistedSpecialPage {


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

Reply via email to