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