AndyRussG has uploaded a new change for review.

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

Change subject: WIP Use per-campaign buckets, with smooth transition
......................................................................

WIP Use per-campaign buckets, with smooth transition

Change-Id: I74feda519890a93deae6184bff76f39c741e506c
---
M modules/ext.centralNotice.bannerController/bannerController.js
M modules/ext.centralNotice.bannerController/bannerController.lib.js
2 files changed, 113 insertions(+), 34 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralNotice 
refs/changes/81/174581/1

diff --git a/modules/ext.centralNotice.bannerController/bannerController.js 
b/modules/ext.centralNotice.bannerController/bannerController.js
index 79eb55a..3ce5415 100644
--- a/modules/ext.centralNotice.bannerController/bannerController.js
+++ b/modules/ext.centralNotice.bannerController/bannerController.js
@@ -26,9 +26,7 @@
  */
 ( function ( $, mw ) {
 
-       var rPlus = /\+/g,
-               bucketValidityFromServer = mw.config.get( 
'wgNoticeNumberOfBuckets' )
-                       + '.' + mw.config.get( 
'wgNoticeNumberOfControllerBuckets' );
+       var rPlus = /\+/g;
 
        function decode( s ) {
                try {
@@ -113,6 +111,17 @@
                 */
                deferredObjs: {},
 
+               /**
+                * Check if we're configured to choose banners on the client,
+                * and do a few sanity checks. Since bannercontroller.lib and
+                * bannerChoiceData are dependencies, it should be safe to 
assume the
+                * data's there by the time this module executes.
+                */
+               chooseBannerOnClient:
+                               mw.config.get( 
'wgCentralNoticeChooseBannerOnClient' ) &&
+                               mw.cnBannerControllerLib &&
+                               ( mw.cnBannerControllerLib.choiceData !== null 
),
+
                /** -- Functions! -- **/
                loadBanner: function () {
                        if ( mw.centralNotice.data.getVars.banner ) {
@@ -161,11 +170,14 @@
                                },
                                scriptUrl;
 
-                       // Check if we're configured to get choose banners on 
the client,
-                       // and do a few sanity checks.
-                       if ( mw.config.get( 
'wgCentralNoticeChooseBannerOnClient' ) &&
-                               mw.cnBannerControllerLib &&
-                               mw.cnBannerControllerLib.choiceData !== null ) {
+                       // Either choose the banner on the client, or call the 
server to get
+                       // a random banner.
+                       if ( mw.centralNotice.chooseBannerOnClient ) {
+
+                               // Do all things bucket. Retrieve or generate 
buckets for all
+                               // the campaigns mentioned in choiceData. Then 
update expiry
+                               // dates and remove expired buckets as 
necessary.
+                               mw.cnBannerControllerLib.processBuckets();
 
                                // Filter choice data and calculate allocations
                                mw.cnBannerControllerLib.filterChoiceData();
@@ -233,30 +245,26 @@
                                mw.centralNotice.data.getVars[decode( p1 )] = 
decode( p2 );
                        } );
                },
+               /**
+                * Legacy function for getting the legacy global bucket. Left 
here for
+                * compatibility; may be deprecated soon.
+                */
                getBucket: function() {
-                       var dataString = $.cookie( 'centralnotice_bucket' ) || 
'',
-                               bucket = dataString.split('-')[0],
-                               validity = dataString.split('-')[1];
-
-                       if ( ( bucket === null ) || ( validity !== 
bucketValidityFromServer ) ) {
-                               bucket = Math.floor(
-                                       Math.random() * mw.config.get( 
'wgNoticeNumberOfControllerBuckets' )
-                               );
+                       var bucket = 
mw.cnBannerControllerLib.retrieveLegacyBucket();
+                       if ( !bucket ) {
+                               bucket = 
mw.cnBannerControllerLib.getRandomBucket();
                        }
-
                        return bucket;
                },
                /**
-                * Puts the bucket in mw.centralNotice.data.bucket in a bucket 
cookie.
-                * If such a cookie already exists, extends its expiry date as
-                * indicated by wgNoticeBucketExpiry.
+                * Legacy function for storing the legacy gloabl bucket. Left 
here for
+                * compatibility; may be deprecated soon. Stores
+                * mw.centralNotice.data.bucket. See
+                * mw.cnBannerControllerLib.storeLegacyBucket.
                 */
                storeBucket: function() {
-                       $.cookie(
-                               'centralnotice_bucket',
-                               mw.centralNotice.data.bucket + '-' + 
bucketValidityFromServer,
-                               { expires: mw.config.get( 
'wgNoticeBucketExpiry' ), path: '/' }
-                       );
+                       mw.cnBannerControllerLib.storeLegacyBucket(
+                               mw.centralNotice.data.bucket );
                },
                initialize: function () {
                        // === Do not allow CentralNotice to be re-initialized. 
===
@@ -269,11 +277,15 @@
                        mw.centralNotice.loadQueryStringVariables();
 
                        // === Initialize things that don't come from MW itself 
===
-                       mw.centralNotice.data.bucket = 
mw.centralNotice.getBucket();
                        mw.centralNotice.data.country = 
mw.centralNotice.data.getVars.country || window.Geo.country || 'XX';
                        mw.centralNotice.data.addressFamily = ( window.Geo.IPv6 
|| window.Geo.af === 'v6' ) ? 'IPv6' : 'IPv4';
                        mw.centralNotice.isPreviewFrame = (mw.config.get( 
'wgCanonicalSpecialPageName' ) === 'BannerPreview');
                        mw.centralNotice.data.device = 
mw.centralNotice.data.getVars.device || mw.config.get( 'wgMobileDeviceName', 
'desktop' );
+
+                       // Use legacy bucket if we're not choosing banners on 
the client
+                       if ( !mw.centralNotice.chooseBannerOnClient ) {
+                               mw.centralNotice.data.bucket = 
mw.centralNotice.getBucket();
+                       }
 
                        // === Do not actually load a banner on a special page 
===
                        //     But we keep this after the above initialization 
for CentralNotice pages
@@ -357,10 +369,13 @@
                        impressionData.banner = bannerJson.bannerName;
                        impressionData.campaign = bannerJson.campaign;
 
-                       // Store the bucket we used in a cookie. If it's 
already there, this
-                       // should extend the bucket cookie's expiry the duration
+                       // Legacy bucket operation. If we're not choosing 
banners on the
+                       // client, store the bucket we used in a cookie. If 
it's already
+                       // there, this should extend the bucket cookie's expiry 
the duration
                        // indicated by wgNoticeBucketExpiry.
-                       mw.centralNotice.storeBucket();
+                       if ( mw.centralNotice.chooseBannerOnClient ) {
+                               mw.centralNotice.storeBucket();
+                       }
 
                        // Get the banner type for more queryness
                        mw.centralNotice.data.category = encodeURIComponent( 
bannerJson.category );
diff --git a/modules/ext.centralNotice.bannerController/bannerController.lib.js 
b/modules/ext.centralNotice.bannerController/bannerController.lib.js
index 8e7fcaa..8304dca 100644
--- a/modules/ext.centralNotice.bannerController/bannerController.lib.js
+++ b/modules/ext.centralNotice.bannerController/bannerController.lib.js
@@ -1,8 +1,17 @@
 ( function ( $, mw ) {
 
+       bucketValidityFromServer = mw.config.get( 'wgNoticeNumberOfBuckets' )
+               + '.' + mw.config.get( 'wgNoticeNumberOfControllerBuckets' );
+
        // FIXME Temporary location of this object on the mw hierarchy. See 
FIXME
        // in bannerController.js.
        mw.cnBannerControllerLib = {
+
+               choiceData: null,
+
+               bucketsByCampaign: null,
+
+               possibleBanners: null,
 
                /**
                 * Set possible campaign and banner choices. Called by
@@ -12,9 +21,63 @@
                        this.choiceData = choices;
                },
 
-               choiceData: null,
+               /**
+                * Do all things bucket:
+                *
+                * - Go through choiceData and retrieve or generate buckets for 
all
+                *   campaigns. If we don't already have a bucket for a 
campaign, but
+                *   we still have legacy buckets, copy those in. Otherwise 
choose a
+                *   random bucket.
+                *
+                * - Go through all the buckets stored, updating expiry dates 
and
+                *   purging expired buckets as necessary.
+                *
+                * - Store the updated bucket data in a cookie.
+                */
+               processBuckets: function() {
+                       // WIP, FIXME
+               },
 
-               possibleBanners: null,
+               /**
+                * Get a random bucket (integer greater or equal to 0 and less 
than
+                * wgNoticeNumberOfControllerBuckets).
+                *
+                * @returns int
+                */
+               getRandomBucket: function() {
+                       return Math.floor(
+                               Math.random() * mw.config.get( 
'wgNoticeNumberOfControllerBuckets' )
+                       );
+               },
+
+               /**
+                * Retrieve the user's legacy global bucket from the legacy 
bucket
+                * cookie. Follow the legacy procedure for determining 
validity. If a
+                * valid bucket was available, return it, otherwise return null.
+                */
+               retrieveLegacyBucket: function() {
+                       var dataString = $.cookie( 'centralnotice_bucket' ) || 
'',
+                               bucket = dataString.split('-')[0],
+                               validity = dataString.split('-')[1];
+
+                       if ( ( bucket === null ) || ( validity !== 
bucketValidityFromServer ) ) {
+                               return null;
+                       }
+               },
+
+               /**
+                * Store the legacy bucket.
+                * Puts bucket in a the legacy global bucket cookie.
+                * If such a cookie already exists, extends its expiry date as
+                * indicated by wgNoticeBucketExpiry.
+                */
+               storeLegacyBucket: function( bucket ) {
+                       $.cookie(
+                               'centralnotice_bucket',
+                               bucket + '-' + bucketValidityFromServer,
+                               { expires: mw.config.get( 
'wgNoticeBucketExpiry' ), path: '/' }
+                       );
+               },
 
                /**
                 * Filter the choice data and create a flat list of possible 
banners
@@ -34,11 +97,12 @@
                 */
                filterChoiceData: function() {
 
-                       var i, campaign, j, banner;
+                       var i, campaign, campaignName, j, banner;
                        this.possibleBanners = [];
 
                        for ( i = 0; i < this.choiceData.length; i++ ) {
                                campaign = this.choiceData[i];
+                               campaignName = campaign.name;
 
                                // Filter for country if geotargetted
                                if ( campaign.geotargetted &&
@@ -60,7 +124,7 @@
                                        }
 
                                        // Bucket
-                                       if ( parseInt( 
mw.centralNotice.data.bucket, 10) %
+                                       if ( parseInt( 
this.bucketsByCampaign[campaignName], 10) %
                                                campaign.bucket_count !== 
banner.bucket ) {
                                                continue;
                                        }
@@ -68,7 +132,7 @@
                                        // Add in data about the campaign the 
banner is part of.
                                        // This will be used in the 
calculateBannerAllocations(),
                                        // the next step in choosing a banner.
-                                       banner.campaignName = campaign.name;
+                                       banner.campaignName = campaignName;
                                        banner.campaignThrottle = 
campaign.throttle;
                                        banner.campaignZIndex = 
campaign.preferred;
 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I74feda519890a93deae6184bff76f39c741e506c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralNotice
Gerrit-Branch: master
Gerrit-Owner: AndyRussG <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to