AndyRussG has uploaded a new change for review.

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

Change subject: WIP BannerHistoryLog: timeout for users without sendBeacon
......................................................................

WIP BannerHistoryLog: timeout for users without sendBeacon

Change-Id: I95175dbe538668528c28ede08e87df99014519b8
---
M CentralNotice.modules.php
M CentralNotice.php
M i18n/en.json
M i18n/qqq.json
M resources/subscribing/ext.centralNotice.bannerHistoryLogger.js
5 files changed, 86 insertions(+), 27 deletions(-)


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

diff --git a/CentralNotice.modules.php b/CentralNotice.modules.php
index 4e37b1e..db43f0c 100644
--- a/CentralNotice.modules.php
+++ b/CentralNotice.modules.php
@@ -145,6 +145,8 @@
                'centralnotice-banner-history-logger-max-entry-age-help',
                'centralnotice-banner-history-logger-max-entries',
                'centralnotice-banner-history-logger-max-entries-help',
+               'centralnotice-banner-history-logger-wait-log-no-send-beacon',
+               
'centralnotice-banner-history-logger-wait-log-no-send-beacon-help',
 
                // Legacy campaigns
                'centralnotice-set-record-impression-sample-rate',
diff --git a/CentralNotice.php b/CentralNotice.php
index ddc4371..faff5d7 100644
--- a/CentralNotice.php
+++ b/CentralNotice.php
@@ -268,6 +268,11 @@
                                'type' => 'integer',
                                'labelMsg' => 
'centralnotice-banner-history-logger-max-entries',
                                'helpMsg' => 
'centralnotice-banner-history-logger-max-entries-help'
+                       ),
+                       'waitLogNoSendBeacon' => array(
+                               'type' => 'integer',
+                               'labelMsg' => 
'centralnotice-banner-history-logger-wait-log-no-send-beacon',
+                               'helpMsg' => 
'centralnotice-banner-history-logger-wait-log-no-send-beacon-help'
                        )
                )
        ),
diff --git a/i18n/en.json b/i18n/en.json
index 9441d1f..e4893e9 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -267,6 +267,8 @@
        "centralnotice-banner-history-logger-max-entry-age-help": "Log entries 
older than this will be expired and will not be sent back to the server.",
        "centralnotice-banner-history-logger-max-entries": "Maximum number of 
entries to keep in log",
        "centralnotice-banner-history-logger-max-entries-help": "If more 
history is recorded before the log is sent to the server, the oldest items will 
disappear.",
+       "centralnotice-banner-history-logger-wait-log-no-send-beacon": "Timeout 
for sending the log without sendBeacon (in milliseconds)",
+       "centralnotice-banner-history-logger-wait-log-no-send-beacon-help": "If 
the log is sometimes sent right before navigating to a different page, some 
browsers require a maximum time to wait before giving up on sending the log.",
        "centralnotice-legacy-support": "Legacy support",
        "centralnotice-legacy-support-help": "Settings for compatibility with 
older banners that rely on Special:RecordImpression or include JavaScript that 
hides the banner.",
        "centralnotice-set-record-impression-sample-rate": "Set sample rate for 
Special:RecordImpression",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 0ffbc04..91acd42 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -290,6 +290,8 @@
        "centralnotice-banner-history-logger-max-entry-age-help": "Help text 
for the log expiration age field",
        "centralnotice-banner-history-logger-max-entries": "Label for the 
banner history logger campaign mixin maximum number of log entries control in 
the administration UI",
        "centralnotice-banner-history-logger-max-entries-help": "Help text for 
the maximum log size field",
+       "centralnotice-banner-history-logger-wait-log-no-send-beacon": "Label 
for field for time limit to delay sending the log without sendBeacon, for the 
banner history logger campaign mixin",
+       "centralnotice-banner-history-logger-wait-log-no-send-beacon-help": 
"Help text for field for time limit to delay sending the log without 
sendBeacon, for the banner history logger campaign mixin",
        "centralnotice-legacy-support": "Name of the legacy support campaign 
mixin, for administration UI control",
        "centralnotice-legacy-support-help": "Description of the legacy support 
feature",
        "centralnotice-set-record-impression-sample-rate": "Label for the 
control to activate setting the sample rate for Special:RecordImpression, for 
the legacy support campaign mixin",
diff --git a/resources/subscribing/ext.centralNotice.bannerHistoryLogger.js 
b/resources/subscribing/ext.centralNotice.bannerHistoryLogger.js
index 6f9160c..aa0457d 100644
--- a/resources/subscribing/ext.centralNotice.bannerHistoryLogger.js
+++ b/resources/subscribing/ext.centralNotice.bannerHistoryLogger.js
@@ -10,6 +10,7 @@
        var cn = mw.centralNotice, // Guaranteed to exist; we depend on display 
RL module
                bhLogger,
                mixin = new cn.Mixin( 'bannerHistoryLogger' ),
+               waitLogNoSendBeacon,
                now = Math.round( ( new Date() ).getTime() / 1000 ),
                log,
                readyToLogDeferredObj = $.Deferred(),
@@ -190,6 +191,52 @@
        }
 
        /**
+        * Send the log. If sendBeacon is available, send normally via 
EventLogging.
+        * If not, use an $.ajax with a timeout as per waitLogNoSendBeacon.
+        *
+        * Returns a promise that resolves as soon as the log is sent for users
+        * with sendBeacon. For users without sendBeacon, if the log is sent 
before
+        * the timeout, the promise resolves, otherwise it rejects.
+        *
+        * Note: Do Not Track is already handled at this module's entry points, 
as
+        * well as by EventLogging.
+        *
+        * @param elData Event log data
+        * @returns {jQuery.Promise}
+        */
+       function sendLog( elData ) {
+               var deferred = $.Deferred(),
+                       elPromise;
+
+               // If the browser has sendBeacon, resolve when EventLogging does
+               if ( navigator.sendBeacon ) {
+                       elPromise = mw.eventLog.logEvent( EVENT_LOGGING_SCHEMA, 
elData );
+
+               } else {
+
+                       // No sendBeacon? Do an ajax call and set a time limit 
to wait
+                       // for it to return.
+                       setTimeout( function () {
+                               deferred.reject();
+                       }, waitLogNoSendBeacon );
+
+                       elPromise = $.ajax( {
+                               url: makeEventLoggingURL,
+                               timeout: waitLogNoSendBeacon,
+                               method: 'POST'
+                       } );
+               }
+
+               elPromise.done( function () {
+                       deferred.resolve();
+               } ).fail( function() {
+                       deferred.reject();
+               } );
+
+               return deferred.promise();
+       }
+
+       /**
         * Check the EventLogging URL we'd get from this data isn't too big. 
Here
         * we copy some of the same processes done by ext.eventLogging.
         *
@@ -198,23 +245,24 @@
         * @returns {boolean} true if the EL payload size is OK
         */
        function checkEventLoggingURLSize( elData ) {
+               return ( makeEventLoggingURL( elData ).length <= 
mw.eventLog.maxUrlSize );
+       }
 
-               var fullElData = {
-                               event    : elData,
-                               revision : 13172419, // Coordinate with 
CentralNotice.hooks.php
-                               schema   : EVENT_LOGGING_SCHEMA,
-                               webHost  : location.hostname,
-                               wiki     : mw.config.get( 'wgDBname' )
-                       },
-
-                       url = mw.eventLog.makeBeaconUrl( fullElData );
-
-               return ( url.length <= mw.eventLog.maxUrlSize );
+       function makeEventLoggingURL( elData ) {
+               return mw.eventLog.makeBeaconUrl( {
+                       event    : elData,
+                       revision : 13447710, // Coordinate with 
CentralNotice.hooks.php
+                       schema   : EVENT_LOGGING_SCHEMA,
+                       webHost  : location.hostname,
+                       wiki     : mw.config.get( 'wgDBname' )
+               } );
        }
 
        // Set a function to run after a campaign is chosen and after a banner 
for
        // that campaign is chosen or not
        mixin.setPostBannerHandler( function( mixinParams ) {
+
+               waitLogNoSendBeacon = mixinParams.waitLogNoSendBeacon;
 
                // Bow out if DNT
                if ( doNotTrackEnabled() ) {
@@ -266,20 +314,18 @@
                                // Send a sample to the server
                                if ( Math.random() < rate ) {
 
-                                       mw.eventLog.logEvent(
-                                               EVENT_LOGGING_SCHEMA,
-                                               makeEventLoggingData( rate )
-                                       );
+                                       sendLog( makeEventLoggingData( rate ) 
).always( function () {
 
-                                       inSample = true;
-                                       logSent = true;
+                                               inSample = true;
+                                               logSent = true;
+
+                                               // By resolving only after 
sampling and possibly
+                                               // sending the log, we ensure 
that a sampled log
+                                               // would be sent first. That 
simplifies the logic
+                                               // for whether to send in other 
circumstances.
+                                               readyToLogDeferredObj.resolve();
+                                       } );
                                }
-
-                               // By resolving only after sampling and 
possibly sending the
-                               // log, we ensure that a sampled log would be 
sent first. That
-                               // simplifies the logic for whether to send in 
other
-                               // circumstances.
-                               readyToLogDeferredObj.resolve();
                        } );
                } );
        } );
@@ -319,17 +365,19 @@
                        // It's likely that this will be resolved by the time 
we get here
                        readyToLogDeferredObj.done( function() {
 
+                               // This is included in the done() function to 
ensure a sampled
+                               // log would be sent first (see above).
                                if ( logSent ) {
                                        deferred.resolve();
                                        return;
                                }
 
-                               mw.eventLog.logEvent(
-                                       EVENT_LOGGING_SCHEMA,
-                                       makeEventLoggingData()
-                               ).always( function() {
+                               sendLog( makeEventLoggingData() ).done( 
function() {
                                        deferred.resolve();
+                               } ).fail( function () {
+                                       deferred.reject();
                                } );
+
                        } );
 
                        return deferred.promise();

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I95175dbe538668528c28ede08e87df99014519b8
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralNotice
Gerrit-Branch: master
Gerrit-Owner: AndyRussG <andrew.green...@gmail.com>

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

Reply via email to